home *** CD-ROM | disk | FTP | other *** search
/ LSD Docs / LSD Docs.iso / FILEZ / lsd32.dms / lsd32.adf / AmigaGfx2.pp / AmigaGfx2
Text File  |  1990-09-07  |  178KB  |  5,298 lines

  1.  _________________________________________________________________________
  2. /#########################################################################\
  3. |#####...####..######..######......####...####..#####..##......##......###|
  4. |####.....###..######..########..#####.....###...####..##..######..#######|
  5. |###..###..##..######..########..####..###..##....###..##..######..#######|
  6. |###..###..##..######..########..####..###..##..#...#..##..######......###|
  7. |###.......##..######..########..####.......##..##.....##..######..#######|
  8. |###..###..##..######..########..####..###..##..###....##..######..#######|
  9. |###..###..##...#####...#######..####..###..##..####...##..######..#######|
  10. |###..###..##......##......##......##..###..##..#####..##......##......###|
  11. |#########################################################################|
  12. |####################################################################{RB}#|
  13. |=========================================================================|
  14. |                                      |
  15. |                   ----> PRESENTS <----                  |
  16. |                                      |
  17. |            AMIGA GRAPHICS INSIDE AND OUT - THE COMPLETE BOOK            |
  18. |                                      |
  19. |                    > PART 2 <                  |
  20. |                                      |
  21. | Typed / Scanned / Edited By : RAZOR BLADE.                      |
  22. | Additional Typing by        : GLITCH ( + 8 pages by Asterix ! ).      |
  23. | Original Supplied by          : VIPER                      |
  24. |                                      |
  25. |-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|
  26. |         CALL THE ALLIANCE WORLD HQ -> THE PLACE TO BE             |
  27. |       UNKNOWN PLEASURES --> +44 (0) 823 322 891 --> SYSOP: BARBARIAN    |
  28. |_________________________________________________________________________|
  29.  
  30.  
  31.              CHAPTER 3 - INTUITION - THE USER INTERFACE
  32.  
  33. We begin our trip through the graphic world of the Amiga with a system
  34. component named INTUITION, which refers to a library within the operating
  35. system (see chapter 2). Intuition is directly related to the graphic
  36. libraries' capabilities and is responsible for windows, screens, reqesters,
  37. alerts (Guru Meditations, for example) and much more.
  38.  
  39.                 ----------------------------------------------
  40.  
  41. 3.1  INTUITION WINDOWS.
  42.  
  43. Unless you are running another operating system. Intuition will mamage all
  44. windows. This also applies to the standard windows of the BASIC
  45. interpreter, LIST and BASIC. A data block used for intuition windows
  46. consists of 124 bytes and contains all data specific to a window. The
  47. starting address of the BASIC output window data is always stored in the
  48. variable WINDOW(7). You can obtainn the start address like this:
  49.         
  50.         windo&=WINDOW(8)
  51.  
  52. The data block is stored in the following format:
  53.  
  54.         Data structure  Window/Intuition/124 bytes.
  55.  
  56. OFFSET  TYPE    DEFINITION
  57. ------- ------- ------------------------------------------------
  58. +000    Long    Pointer to next window.
  59. +004    Word    X coordinate of upper left corner.
  60. +006    Word    Y coordinate of upper edge.
  61. +008    Word    Width of window.
  62. +010    Word    Height of Window.
  63. +012    Word    Y coordinate of mouse, rel. to window.
  64. +014    Word    X coordinate of mouse, rel. to window.
  65. +016    Word    Minimum width of window.
  66. +018    Word    Minimum height of window.
  67. +020    Word    Maximum width of window.
  68. +022    Word    Maximim height of window.
  69. +024    Long    Window modes
  70.                 Bit 0:  1=Sizing Gadget Available.
  71.                 Bit 1:  1=Dragbar gadget available.
  72.                 Bit 2:  1=Fore/Background gadgets available.
  73.  
  74.                                 PAGE 93
  75.  
  76. ----------------------------------------------------------------------------
  77.  
  78. WINDOW DATA STRUCTURE (CONT'D) ....
  79.  
  80. OFFSET  TYPE    DEFINITION              
  81. ------- ------- ----------------------------------------------------
  82.  
  83.                 Bit 3:  1=Close gadget available.
  84.                 Bit 4:  1=Sizing gadget is right.
  85.                 Bit 5:  1=Sizing gadget is bottom.
  86.                 Bit 6:  1=Simple refresh.
  87.                 Bit 7:  1=Superbitmap.
  88.                 Bit 8:  1=Backdrop Window.
  89.                 Bit 9:  1=Report Mouse.
  90.                 Bit 10: 1=GimmeZeroZero.
  91.                 Bit 11: 1=Borderless.
  92.                 Bit 12: 1=Activate.
  93.                 Bit 13: 1=This window is active.
  94.                 Bit 14: 1=This window is in request mode.
  95.                 Bit 15: 1=Active window with active menu.
  96.  
  97. +028    Long    Pointer to menu header.
  98. +032    Long    Pointer to title text for this window.
  99. +036    Long    Pointer to first active requester.
  100. +040    Long    Pointer to double click requester.
  101. +044    Word    Number of the window block request.
  102. +046    Long    Pointer to the screen, of this window.
  103. +050    Long    Pointer to the RastPort of this window.
  104. +054    Byte    Left Border.
  105. +055    Byte    Top Border.
  106. +056    Byte    Right Border.
  107. +057    Byte    Bottom Border.
  108. +058    Long    Pointer to border RastPort.
  109. +062    Long    Pointer to the first gadget.
  110. +066    Long    Pointer to previous window (father).
  111. +070    Long    Pointer to next window (child).
  112. +074    Long    Pointer to sprite data for pointer.
  113. +078    Byte    Height of sprite pointer.
  114. +079    Byte    Width of sprite pointer.
  115. +080    Byte    X offset of pointer.
  116. +081    Byte    Y offset of pointer.
  117. +082    Long    IDCMP flags.
  118. +086    Long    User message port.
  119. +090    Long    Window message port.
  120. +094    Long    IntuiMessage message key.
  121. +098    Byte    Detailpen.
  122. +099    Byte    Blockpen.
  123. +100    Long    Pointer to menu checkmarks.
  124. +104    Long    Pointer to screen title text.
  125. +108    Word    GZZ-MouseX
  126. +110    Word    GZZ-MouseY
  127.  
  128.                                 PAGE 94
  129.  
  130. ----------------------------------------------------------------------------
  131.  
  132. Offset  Type    Definition.
  133. ------- ------- --------------------------------------------
  134. +112    Word    GZZ-Width.
  135. +114    Word    GZZ-Height.
  136. +116    Long    Pointer to external data.
  137. +120    Long    Pointer to user data.
  138.  
  139. Every window has a data block like the one in the above format. To access
  140. the different data fields in the data block, first select the desired
  141. output window using the WINDOW OUTPUT statement. After this command, the
  142. data block address will be in the variable WINDOW(7). You add the offset
  143. value of the desired field to this address. There are 3 types of data
  144. fields, byte, word and long. A byte field which consists of exactly one
  145. byte is read with PEEK and is changed with POKE. A word is two bytes wide
  146. and is read and written with PEEKW and POKEW. A long field is four bytes
  147. wide and is read and written with PEEKL and POKEL. We will present several
  148. examples of each.
  149.  
  150.                                 PAGE 95
  151.  
  152. ----------------------------------------------------------------------------
  153.  
  154. 3.2 THE WINDOW DATA STRUCTURE.
  155.  
  156. Now you know the method used to access the data structure of your output
  157. window. The following is a detailed explanation of each data field to
  158. explain what you can do with them.
  159.  
  160.  
  161. OFFSET 0 : POINTER TO NEXT WINDOW.
  162.  
  163. Intuition manages all windows in a type of chain. This offset contains the
  164. starting address of the next window data block. You can find the data block
  165. of the next and previous window from your current data block. This
  166. particular pointer is not important because the chain pointers come later
  167. at offsets 66 and 70.
  168.  
  169.  
  170. OFFSETS 4 AND 6 : POSITION OF WINDOW IN UPPER LEFT HAND CORNER.
  171.  
  172. These two word fields contain the X and Y coordinates of the upper left
  173. hand corner of their window. These coordinates are relative to the
  174. upperleft hand corner of the screen that contains the window. The lines
  175. below provide you with the coordinates:
  176.  
  177.         windo&=WINDOW(7)
  178.         x%=PEEKW(windo&+4)
  179.         y%=PEEKW(windo&+6)
  180.         PRINT "Upper left window corner is at "
  181.         PRINT "Coordinates (";x%;",";y%;")"
  182.         END
  183.  
  184. Because the BASIC output window sits in the upper leeft hand corner of the
  185. Workbench screen you would receive coordinates of (0,0). The moment you
  186. drag this window to a different position, the coordinates are changed.
  187. Later we will use these values to access various intuition routines.
  188.  
  189.  
  190. OFFSETS 8 AND 10 : WINDOW DIMENSIONS.
  191.  
  192. Since we can change the window size with the sizing gadget in the lower
  193. right hand corner of the window, the program doesn't always know the
  194. current window size. The small program below provides the current window
  195. size:
  196.  
  197.                                 PAGE 96
  198.  
  199. -----------------------------------------------------------------------------
  200.  
  201.         windo&=WINDOW(7)
  202.         windoWidth%=PEEKW(windo&+8)
  203.         windoHeight%=PEEKW(windo&+10)
  204.         PRINT "At the moment your window is ";windoWidth%
  205.         PRINT "pixels wide and ";windoHeight%;" Pixels high."
  206.         END
  207.  
  208. OFFSETS 12 AND 14 : MOUSE COORDINATES.
  209.  
  210. These two word fields contain the actual mouse coordinates relative to the
  211. upper left hand corner of the window. The first field contains the Y
  212. coordinate and the second field the X coordinate.
  213.  
  214. Using these two values you can easily create a small drawing program. The
  215. following lines demonstrate this:
  216.  
  217.         '##################################
  218.         '#
  219.         '# Section:  3.2
  220.         '# Program:  Mouse Draw I
  221.         '# Date   :  04/05/87
  222.         '# Author :  tob
  223.         '# Version:  1.0
  224.         '#
  225.         '###################################
  226.  
  227.         init:   windo&=WINDOW(7)
  228.                 'Address of window structure
  229.         loop:   'wait for key press
  230.                 PRINT "Press any key to exit"
  231.                 WHILE INKEY$ = ""
  232.                    mouse.y% = PEEKW(windo&+12)
  233.                    mouse.x% = PEEKW(windo&+14)
  234.                    PSET(mouse.x%,mouse.y%)
  235.                 WEND
  236.  
  237. Two things are immediately visible. First the line drawn starts several
  238. pixels below the mouse pointer and second, only a dotted line is being
  239. drawn. The mouse position fields contain the mouse coordinates relative to
  240. the upper left hand corner of the window. However, PSET draws in a plane
  241. that uses an offset relative to the upper left hand corner of the drawing
  242. plane and not the window (as long as the window is a GimmeZeroZero window;
  243. we will have more on this later). To correct the window/plane problem,
  244. subtract 11 from the Y value and 4 from the X value. The second problem is
  245. caused by BASIC's slow speed. The mouse moves faster than BASIC can draw.
  246. Test this by moving the mouse very slowly across the screen. You should see
  247. a complete line from one point to another. The next program contains both
  248. changes :
  249.  
  250.                                 PAGE 97
  251.  
  252. ----------------------------------------------------------------------------
  253.  
  254.         '###################################
  255.         '#
  256.         '# Section: 3.2B
  257.         '# Program: Mouse Draw II
  258.         '# Date   : 04/05/87
  259.         '# Author : tob
  260.         '# Version: 1.0
  261.         '#
  262.         '###################################
  263.         init:   windo&=WINDOW(7)
  264.                 '* Address of Window Data Structure.
  265.                 mouse.y% = PEEKW(windo&+12)-11
  266.                 mouse.x% = PEEKW(windo&+14)-4
  267.         loop:   '* Wait for keypress.
  268.                 PRINT "Press any key to Exit"
  269.                 WHILE INKEY$=""
  270.                     oldmouse.y% = mouse.y%
  271.                     oldmouse.x% = mouse.x%
  272.                     mouse.y% = PEEKW(windo&+12)-11
  273.                     mouse.x% = PEEKW(windo&+14)-4
  274.                     LINE(oldmouse.x%,oldmouse.y%)-(mouse.x%,mouse.y%)
  275.                 WEND
  276.  
  277. When you speed around the screen with this program, you will discover that
  278. individual "peaks" appear. This happens when the mouse coordinates are
  279. calculated but the Y value has not changed.
  280.  
  281.      
  282. OFFSET 16,18,20 AND 22: WINDOW LIMITS.
  283.  
  284. Some windows can be made larger and smaller using the mouse. Every window
  285. has it's own maximum and minimum size. A window can be any size within
  286. these limits in the window data structure.
  287.  
  288.         windo&=WINDOW(7)
  289.         min.x%=PEEKW(windo&+16)
  290.         min.y%=PEEKW(windo&+18)
  291.         max.x%=PEEKW(windo&+20)
  292.         max.y%=PEEKW(windo&+22)
  293.         PRINT "Minimum Size: X=";min.x%;
  294.         PRINT " Y=";min.y%
  295.         PRINT "Maximum Size: X=";max.x%;
  296.         PRINT " Y=";max.y%
  297.         END
  298.  
  299. In this example we read the limit values. You can easily set your own
  300. window limits by using POKEW to the required addresses:
  301.  
  302.         windo&=WINDOW(7)
  303.         min.x%=5
  304.         min.y%=7
  305.         max.x%=640
  306.         max.y%=200
  307.         POKEW,windo&+16,min,x%
  308.         POKEW,windo&+18,min.y%
  309.         POKEW,windo&+20,max.x%
  310.         POKEW,windo&+22,max.y%
  311.         END
  312.  
  313.                                 PAGE 98
  314.  
  315. -----------------------------------------------------------------------------
  316.  
  317. There are two things you must always be sure of:
  318.  
  319. 1.) The minimum size has to be smaller than the maximum size.
  320.  
  321. 2.) The maximum size cannot be smaller than the current window you are
  322.     changing. (Dimensions are available fromm offsets 8 and 10).
  323.  
  324.  
  325. OFFSET 24: WINDOW MODES.
  326.  
  327. Intuition has different window types and each window can have various
  328. gadgets assigned to them :
  329.  
  330.         a.)     Sizing gadget.
  331.         b.)     Dragbar.
  332.         c.)     Fore/Background gadget.
  333.         d.)     Close gadget.
  334.  
  335. You can also set the refresh mode for the window. This mode determines how
  336. a window is restored once another window covers it. SIMPLE REFRESH leaves
  337. the restoring up to you. Normally this means that if another window covers
  338. your window, the covered part is lost. SMART REFRESH uses Intuition to save
  339. the covered portion of the window and restores it after the window is
  340. uncovered. This method requires more time and can use much more memory,
  341. depending on how many windows are active. The SUPERBIT method keeps a copy
  342. of the entire window contents in RAM. Although this expends a large amount
  343. of memory, it allows a window to show a piece of a much larger graphic.
  344.  
  345. Besides the basic attributes of a window, there are also special windows. A
  346. BACKDROP window is always behind all other windows and cannot be put in
  347. front. For example, it works as the background or graphic plane. The
  348. visible workbench screen is nothing more than a backdrop window the covers
  349. the screen. A GimmeZeroZero window has two parts, a border and a drawing
  350. plane. This method allows easy drawing because it is impossible to
  351. accidentally draw over the border. The BASIC window is an example of a
  352. GimmeZeroZero window. The BORDERLESS window does not have a borderr frame.
  353. An example of this type is the backdrop Workbench window because it does
  354. not have a borderr frame and it merges with the background.
  355.  
  356. To access these modes use the bit pattern from the table in section 3.1
  357.  
  358. NOTE: Changes to this field only take effect after workbench refreshes the 
  359.       window (for example, when you drag it to move it).
  360.  
  361.                                 PAGE 99
  362.  
  363. ------------------------------------------------------------------------------
  364.  
  365. OFFSET 28: THE MENU HEADER.
  366.  
  367. A special property of all intuition windows is their ability to have menus.
  368. When you press the right mouse button the menus appear in the top window
  369. bar.
  370.  
  371. This field contains the pointer to the intuition menu system for this
  372. window.
  373.  
  374.  
  375. OFFSET 32: TITLE TEXT FOR THE WINDOW.
  376.  
  377. Every window has it's own name. This offsett contains the starting address
  378. for the title text. The following lines demonstrate an easy way to change
  379. this:
  380.  
  381.         window.name$="Hello World"+CHR$(0)
  382.         POKEL WINDOW(7)+32,SADD(window.name$)
  383.  
  384. As soon as you perform an action with the window, such as dragging (cuasing
  385. intuition to refresh the window), the new menu name appears. Later we will
  386. show you a method for changing a window name that will give you instant
  387. results.
  388.  
  389. The CHR$(0) is a null byte added at the end of the text that tells
  390. Intuition where the text ends.
  391.  
  392.  
  393. OFFSET 36,40 AND 44: REQUESTER HANDLING.
  394.  
  395. Intuition uses this data field to remember how many (and what kind) of
  396. requesters are blocked by this window. Basic programmers can ignore this
  397. field for now.
  398.  
  399.  
  400. OFFSET 46: POINTER TO SCREEN.
  401.  
  402. Windows with complete freedom of movement do not exist. Every window
  403. appears in a screen. The Workbench screen is the first screen and the other
  404. screens can be overlaid by using the SCREEN statement. This offset contains
  405. the address of the Intuition screen data structure. In the same way that
  406. each window has it's own data structure, each screen has its own data
  407. structure. Screen data is arranged somewhat differently. We will discuss
  408. that in more detail later.
  409.  
  410.  
  411. OFFSET 50: POINTER TO RASTPORT OF WINDOW.
  412.  
  413. The RastPort is nothing more than another data structure. It could be
  414. defined as an intersection. From the RastPort there are paths to windows,
  415. screens and even the most simple graphic components like bit-maps and
  416. layers. We will discuss all of these in detail later.
  417.  
  418.                                 PAGE 100
  419.  
  420. ----------------------------------------------------------------------------
  421.  
  422. OFFSET 54,55,56 AND 57: WINDOW BORDERS.
  423.  
  424. This 4 byte field contains the dimensions in pixels of the window border.
  425. When we were working with the mouse coordinates (offset 12,14) we
  426. subtracted the values 11 and 4. The same values are located here; they are
  427. the height of the top border and the width of the left border.
  428.  
  429. You can calculate the drawing coordinates in a GimmeZeroZero window by
  430. adding these values. This determines your relative position to the top left
  431. hand corner of the window.
  432.  
  433. When working with other window types you have to be careful not to draw
  434. over the window border. The following rules can help you avoid this:
  435.  
  436. a.) Your X coordinate must be greater than the window border and smaller
  437.     than the width of the window (offset 8) minus the width of the right
  438.     border.
  439.  
  440. b.) Follow the same rule for the Y coordinates.
  441.  
  442.  
  443. OFFSET 58: THE RASTPORT BORDER.
  444.  
  445. All GimmeZeroZero windows control two independant drawing planes: the
  446. window border and the window contents. This offset contains the address
  447. pointer for the RastPort of a GimmeZeroZero window. The following program
  448. uses the RastPort border and the Graphic function TEXT to display a status
  449. line in the window header:
  450.  
  451.         '###############################
  452.         '#
  453.         '# section: 3.2C       
  454.         '# Program: Status Line                                 
  455.         '# Date   : 12/17/89                                    
  456.         '# Author : tob                                 
  457.         '# Version: 1.0
  458.         '#
  459.         '###############################
  460.  
  461.         ' This program creates a user status liine in a 
  462.         ' GimmeZeroZero window. BorderRastPort is the
  463.         ' length of x. x is independant of the actual window 
  464.         ' size. Error checking prevents any Gadgets from 
  465.         ' being disturbed.
  466.  
  467.         PRINT "Searching for .bmap file ...."
  468.  
  469.  
  470.                                 PAGE 101
  471.  
  472. -----------------------------------------------------------------------------
  473.  
  474.         'graphics.library
  475.         'Text()
  476.         'SetAPen()
  477.         'SetDrMd()
  478.         'Move()
  479.  
  480.         LIBRARY "graphics.library"
  481.  
  482.         main:   CLS
  483.                 Status "STATUS: Demo window. Please press a key!",60
  484.                 WHILE INKEY$=""
  485.                 WEND
  486.                 WHILE yn$<>"y"
  487.                    Status "STATUS: Please enter your name!",60
  488.                    CLS
  489.                    LOCATE 1,1
  490.                    LINE INPUT "--> ";n$
  491.                    Status "Name: "+n$+". Correct (y/n) ? ",60
  492.                    LOCATE 1,1
  493.                    PRINT SPACE$(50)
  494.                    LOCATE 1,1
  495.                    LINE INPUT "--> ";yn$       
  496.                 WEND
  497.  
  498.         endprog: WINDOW 1,""            
  499.                  LIBRARY CLOSE
  500.                  END
  501.  
  502.         SUB Status(text$,t.width%) STATIC
  503.                 borderRast%     = PEEKL(WINDOW(7)+58)
  504.                 IF borderRast% = 0 THEN
  505.                    BEEP
  506.                    PRINT "This is not a GimmeZeroZero type window."
  507.                    ERROR 255
  508.                 END IF
  509.  
  510.                 windoWidth% = PEEKW(WINDOW(7)+8)
  511.                 maxchar%    = INT((windoWidth%-86)/8)
  512.                 TextLen%    = LEN(text$)
  513.                 IF t.width% = 0 THEN t.width% = TextLen%
  514.                 IF t.width% < maxChar% THEN maxChar%=t.width%
  515.                 IF TextLen% < t.width% THEN
  516.                    text$=text$+SPACE$(t.width%-TextLen%)
  517.                 END IF
  518.                 CALL SetAPen(borderRast&,1)
  519.                 CALL Move(borderRast&,32,7)
  520.                 CALL text(borderRast&,SADD(text$),maxChar%)
  521.                 CALL SetDrMd(borderRast&,0)             
  522.                 CALL SetAPen(borderRast&,3)
  523.                 CALL Move(borderRast&,31,7)
  524.                 CALL text(borderRast,SADD(text$),maxchar%)
  525.                 CALL SetDrMd(borderRas&,1)
  526.         END SUB
  527.  
  528.                                 PAGE 102
  529.  
  530. ----------------------------------------------------------------------------
  531.  
  532. OFFSET 62: FIRST GADGET.
  533.  
  534. Gadgets are small (or large) "switch elements" that you select with the
  535. mouse. Among these are the on/off gadget and the sizing gadget. This offset
  536. contains the address of the first gadget structure in a chain. BASIC users
  537. can disregard this.
  538.  
  539.  
  540. OFFSETS 66 AND 70: FATHER AND CHILD WINDOWS.
  541.  
  542. In our discussion of offset 0 we mentioned that Intuition manages all
  543. windows in a data chain. Every window has it's own data structure block. In
  544. each data structure there is a pointer to the previous (father) window and
  545. to the next (child) window. The first window in a chain does not have a
  546. father pointer (=0) and the last has no child pointer (=0).
  547.  
  548. These two fields are very important. Up until now it was possible for us to
  549. determine the address of the output window by using the variable WINDOW(7).
  550. Now we can use a window to determine where the data for any window is
  551. located. The following program demonstrates this:
  552.  
  553.         '#######################################
  554.         '#
  555.         '# section: 3.2
  556.         '# Program: Window Finder.
  557.         '# Date   : 04/05/87
  558.         '# Author : tob 
  559.         '# Version: 1.0
  560.         '#
  561.         '########################################
  562.  
  563.         init:   windo& = WINDOW(7)
  564.  
  565.         '* Here we search for the end of the data chain.
  566.         '* The 'parent' field of the first element is zero.
  567.  
  568.         WHILE found% = 0
  569.             parent.windo& = PEEKL(windo&+66)
  570.             IF parent.windo&= 0 THEN
  571.                 found% = 1
  572.             ELSE
  573.                 windo& = parent.windo&
  574.             END IF
  575.         WEND
  576.         found% = 0
  577.  
  578.         '* Windo& contains the address of the window
  579.         '* Data block of the first window in the Data
  580.         '* chain. Now we read through the chain, until 
  581.         '* the 'child' field equals zero.
  582.  
  583.                                 PAGE 103
  584.  
  585. ----------------------------------------------------------------------------
  586.  
  587.         WHILE found% = 0
  588.             counter% = counter%+1
  589.             PRINT counter%;
  590.             PRINT ". Window:"
  591.             PRINT "Address of data structure: ";windo&
  592.  
  593.         '* now we provide the name of the window found at offset +32
  594.  
  595.             PRINT "Name of Window :            ";
  596.             windo.name& = PEEKL(windo&+32)
  597.             WHILE done% = 0
  598.                 gef$ = CHR$(PEEK(windo.name&))
  599.                 IF gef$ = CHR$(0) THEN
  600.                     done% = 1
  601.                     PRINT
  602.                 ELSE
  603.                     PRINT gef%;
  604.                     windo.name& = windo.name&+1
  605.                 END IF
  606.             WEND
  607.             PRINT
  608.             done% = 0
  609.             child.windo& = PEEKL(windo&+70)
  610.             IF child.windo&= 0 THEN
  611.                 found% = 1
  612.             ELSE
  613.                 windo& = child.windo&
  614.             END IF
  615.         WEND
  616.  
  617. Using these methods you have complete control of all the intuition managed
  618. windows. You can write into other windows, change their names etc.. We will
  619. present more programs further on that demonstrate this.
  620.  
  621.  
  622. OFFSET 74,78,79,80 AND 81: THE SPRITE IMAGE.
  623.  
  624. It is possible for every window to have it's own mouse pointer. This offset
  625. has the address pointer to the data for the new pointer's sprite image, the
  626. height and width (maximum 16 pixels). Changing the value of this offset
  627. doesn't accomplish anything. To set up your custom pointer, use SETPOINTER
  628. via intuition. We show an example of how to do this at the end of the
  629. chapter.
  630.  
  631.  
  632. OFFSET 82,86,90 AND 94: IDCMP FLAGS AND MESSAGE PORTS.
  633.  
  634. IDCMP stands for INTUITION DIRECT COMMUNICATION MESSAGE PORT. Intuition
  635. communicates through this channel with other tasks such as BASIC. This is
  636. not important to you as a BASIC programmer since Intuition receives the
  637. messages from BASIC and processes them automatically.
  638.  
  639.                                 PAGE 104
  640.  
  641. ------------------------------------------------------------------------------
  642.  
  643. OFFSET 98 AND 99: WINDOW COLOURS.
  644.  
  645. The window determines it's two colours from these two byte fields where the
  646. colour registers are stored. You can change the window colours by poking
  647. new values here. As before, intuition does not make the changes until a
  648. window refresh is prompted (and window action such as dragging or sizing).
  649.  
  650.  
  651. OFFSET 100: THE CHECK MARK IMAGE.
  652.  
  653. This offset contains the address of a small graphic image. You have
  654. probably seen a menu option that sets a specific menu option on and marks
  655. it with a check mark. The default value of this offset is zero for the
  656. standard check mark image.
  657.  
  658.  
  659. OFFSET 104: THE SCREEN TITLE.
  660.  
  661. A screen, that contains your window, can have different names. The screen
  662. name depends on which window is selected (=active). Each window can give
  663. the screen a different name. This offset holds the address pointer of the
  664. name text.
  665.  
  666.  
  667. OFFSET 108,110,112 AND 114: GIMMEZEROZERO PARAMETERS.
  668.  
  669. These fields are used only for a GimmeZeroZero window. GZZ-MouseX and
  670. GZZ-MouseY contain relative values to offsets 12 and 14. They specify the
  671. coordinates of the mouse pointer relative to the drawing plane, not to the
  672. window. The zero coordinate is the upper left hand corner of the window
  673. contents, not the upper left hand corner of the window border.
  674.  
  675. GZZ-width and GZZ-height contain values relative to offset fields 8 and 10.
  676. The width and height of the window contents without the border are stored
  677. here.
  678.  
  679.  
  680. OFFSET 116 AND 120: OPTIONAL POINTERS.
  681.  
  682. These two pointers are used to link data blocks of different types with the
  683. standard structure. The first pointer is reserved for Intuition, the second
  684. is available for the user.
  685.  
  686.                                 PAGE 105
  687.  
  688. -----------------------------------------------------------------------------
  689.  
  690. 3.3 FUNCTIONS OF THE INTUITION LIBRARY.
  691.  
  692. Now that we understand how intuition manages window we can look at the
  693. intuition library. The following routines of the intuition library are
  694. responsible for windows:
  695.  
  696.         SetPointer()
  697.         ClearPointer()
  698.         MoveWindow()
  699.         SizeWindow()
  700.         WindowLimits()
  701.         WindowToBack()
  702.         WindowToFront()
  703.  
  704.                 ------------------------------------------------
  705.  
  706. 3.3.1  A PERSONALISED MOUSE POINTER.
  707.  
  708. The SetPointer function makes it possible for you to create your own
  709. personalised mouse pointer for your window. As soon as your window is
  710. active the normal pointer will be replaced by yours.
  711.  
  712.  
  713. This function requires six parameters:
  714.  
  715.         SetPointer(window,image,height,width,xOff,yOff)
  716.         Window: Address of window data structure of that window.
  717.         image : Address of sprite image block.
  718.         height: Height of the sprite.
  719.         width : Width of sprite (max.16)
  720.         xOff  : Marks the "hot spot"
  721.         yOff  : Marks the "hot spot"
  722.  
  723. The following is an example program which shows how to change the mouse
  724. pointer.
  725.  
  726.         '######################################
  727.         '#
  728.         '# section: 3.3.1
  729.         '# Program: SetPointer-ClearPointer.
  730.         '# Date   : 04/05/87
  731.         '# Author : tob
  732.         '# Version: 1.0
  733.         '#
  734.         '#######################################
  735.  
  736.                                 PAGE 106
  737.  
  738. ----------------------------------------------------------------------------
  739.  
  740.         ' The Amiga standard mouse pointer is
  741.         ' replaced by a user-defined pointer.
  742.  
  743.         PRINT "Searching for .bmap file...."
  744.  
  745.         'INTUITION-Library
  746.         'SetPointer()
  747.         'ClearPointer()
  748.         LIBRARY "intuition.library"
  749.  
  750.         init:   image$=""
  751.                 sprite.height% = 14
  752.                 sprite.width% = 16
  753.                 sprite.xOff% = -7
  754.                 sprite.yOff% = -6
  755.  
  756.         image:  '* REad sprite data image.
  757.                 RESTORE sprite.data
  758.                 FOR loop% = 0 TO 31
  759.                     READ info&
  760.                     hi% = INT(info&/256)
  761.                     lo% = info& - (256*hi%)
  762.                     image$ = image$+CHR$(hi%)+CHR$(lo%)
  763.                 NEXT loop
  764.  
  765.         setpoint:  '* Build new image.
  766.                    CALL SetPointer(WINDOW(7),SADD(image$),sprite.height%,
  767.                         sprite.width%,sprite.xOff%,sprite.yOff%)
  768.         maindemo:  '* Demonstration of the new pointer.
  769.                    CLS
  770.                    PRINT "Any key to exit."
  771.                    PRINT "Left Mouse button to draw."
  772.  
  773.                    '* Draw with pattern.
  774.                    area.pat%(0) = &h1111
  775.                    area.pat%(1) = &h2222
  776.                    area.pat%(2) = &h4444
  777.                    area.pat%(3) = &h8888
  778.                    PATTERN , area.pat%
  779.                    COLOR 2,3
  780.  
  781.                    WHILE INKEY$=""
  782.                       state% = MOUSE(0)
  783.                       IF state%<0 THEN
  784.                         mouseOldX% = mouseX%
  785.                         mouseOldY% = mouseY%
  786.                         mouseX% = MOUSE(1)
  787.                         mouseY% = MOUSE(2)
  788.                         IF lplot% = 0 THEN
  789.                             lplot% = 1
  790.  
  791.  
  792.                                 PAGE 107
  793.  
  794. ----------------------------------------------------------------------------
  795.  
  796.                             PSET(mouseX%,mouseY%)
  797.                         ELSE
  798.                           LINE(mouseOldX%,mouseOldY%)-(mouseX%,mouseY%),1,bf
  799.                         END IF
  800.                       ELSE
  801.                         lplot% = 0
  802.                       END IF
  803.                    WEND
  804.  
  805.                    COLOR 1,0
  806.  
  807.         endprog:   '* End demo and restore old pointer.
  808.                    CALL ClearPointer(WINDOW(7))
  809.                    LIBRARY CLOSE
  810.                    END
  811.  
  812.         sprite.data:    DATA 0,0   
  813.                         DATA 256,256
  814.                         DATA 256,256
  815.                         DATA 256,256
  816.                         DATA 896,0
  817.                         DATA 3168,0
  818.                         DATA 12312,0
  819.                         DATA 256,49414
  820.                         DATA 256,49414
  821.                         DATA 12312,0
  822.                         DATA 3168,0
  823.                         DATA 896,0
  824.                         DATA 256,256
  825.                         DATA 256,256
  826.                         DATA 256,256
  827.                         DATA 0,0
  828.  
  829. PROGRAM DESCRIPTION:
  830.  
  831. Our new mouse pointer should be 16 pixels wide and 14 pixels high. The "hot
  832. spot", the sensitive pixel of the pointer, is seven pixels to the right and
  833. six pixels below the upper left hand corner of the sprite.
  834.  
  835. The program routine IMAGE defines the shape of the new pointer. The data
  836. for the shape is stored in the section called SPRITE.DATA. Each row of a
  837. sprite can be a maximum of 16 pixels wide. The data block is composed of
  838. two 16 bit values per sprite row. Since our sample sprite is 14 rows high
  839. there has to be 14*2 = 28 data elements (plus two zeros at the beginning
  840. and emd to switch of DMA). For every possible pixel of the sprite there are
  841. two bits. If neither bit is set the pixel will be transparent. The
  842. remaining three combinations determine which of the three possible colours
  843. the pixel will be.
  844.  
  845. The sprite data is stored in the string variable IMAGE$. To do this the
  846. 16bit values are first converted to two 8 bit values (lo and hi byte).
  847.  
  848. Finally we call SetPointer to activate the new pointer.
  849.  
  850. At the end of the program we use ClearPointer to restore the normal
  851. pointer.
  852.  
  853.                                 PAGE 108
  854.  
  855. ----------------------------------------------------------------------------
  856.  
  857. 3.3.2  MOVING WINDOWS MADE EASY.
  858.  
  859. Instead of using the mouse to drag windows around the screen, you can
  860. program Intuition to do the same thing. You can use the intuition routine
  861. "MoveWindow" which requires three parameters:
  862.  
  863.         MoveWindow(window,deltaX,deltaY)
  864.  
  865.         window: Address of the window data structure            
  866.         deltaX: Number of pixels to move the window to the right.
  867.                 (left = negative)
  868.         deltaY: Same in vertical direction.
  869.  
  870. These routines do not check your parameters for valid coordinates. If your
  871. delta values set coordinates outside the screen, Intuition will try to move
  872. your window off the monitor. Of course, this will not work. To prevent this
  873. from happening we have added a small error check routine to the next
  874. program. This routine will check your input with the data in the window
  875. data structure (Section 2.2).
  876.  
  877. This program is a SUB named Move.
  878.  
  879.         '##############################
  880.         '#
  881.         '# Section: 3.3.2
  882.         '# Program: Window Move.
  883.         '# Date   : 04/10/87
  884.         '# Author : tob
  885.         '# Version: 1.0
  886.         '#
  887.         '###############################
  888.  
  889.         'Intuition can move selected windows under
  890.         ' program control. This program demonstrates
  891.         ' the WindowMove() command (including
  892.         ' error checking.
  893.  
  894.         PRINT "Searching for .bmap file .... "
  895.  
  896.         'INTUITION-library
  897.         'MoveWindow()
  898.  
  899.         LIBRARY "intuition.library"
  900.  
  901.                                 PAGE 109
  902.  
  903. ----------------------------------------------------------------------------
  904.  
  905.         demo:   CLS
  906.                 WINDOW 2,"Test Window",(10,10)-(400,100),16
  907.                 WINDOW OUTPUT 2
  908.  
  909.                 PRINT "Original Position. Please Press a Key"
  910.                 WHILE INKEY$="": WEND
  911.  
  912.                 Move 10,20  '10 right,20 down
  913.                 PRINT "New position! Press a Key."
  914.                 WHILE INKEY$ = "":WEND
  915.  
  916.                 Move -10,-20 ' 10 left, 20 up
  917.                 PRINT "Returned!!"
  918.  
  919.                 FOR t = 1 TO 3000: NEXT t
  920.  
  921.                 Move 10000,10000
  922.                 ' Nothing happened thanks to the error check.
  923.  
  924.                 WINDOW CLOSE 2
  925.                 LIBRARY CLOSE
  926.  
  927.         SUB Move(x%,y%) STATIC
  928.  
  929.                 win&    = WINDOW(7)
  930.                 screen.width%   = 640
  931.                 screen.height%  = 200 'PAL systems can use 256 here.
  932.                 windo.x%        = PEEKW(win&+4)
  933.                 windo.y%        = PEEKW(win&+6)
  934.                 windo.width     = PEEKW(win&+8)
  935.                 windo.height%   = PEEKW(win&+10)
  936.                 min.x%          = windo.x%*(-1)
  937.                 min.y%          = windo.y%*(-1)
  938.                 max.x%          = screen.width%-windo.width%-windo.x%
  939.                 max.y%          = screen.height%-windo.height%-windo.y%
  940.                 IF x%<min.x% OR x%>max.x% THEN x% = 0
  941.                 IF y%<min.y% OR y%>max.y% THEN y% = 0
  942.                 CALL MoveWindow(win&,x%,y%)
  943.         END SUB
  944.  
  945.                 ---------------------------------------------
  946.  
  947. 3.3.3 SETTING WINDOW LIMITS.
  948.  
  949. All windows that can be sized have a minimum and maximum size. The
  950. Intuition routine WindowLimits sets the limits according to the input
  951. values. The data fields at offset 16 (see section 2.2) are directly
  952. manipulated by WindowLimits. This routine also checks for valid arguments.
  953. When all parameters are OK, WindowLimits returns a TRUE (=1), if not, it
  954. returns a FALSE (=0).
  955.  
  956.                                 PAGE 110
  957.  
  958. ------------------------------------------------------------------------------
  959.  
  960. WindowLimits requires 5 arguments and returns a result:
  961.  
  962. result% = WindowLimits%(window,minX,minY,maxX,maxY)
  963.  
  964.         result% = 1= all OK
  965.                   0= Minimum size greater than maximim size etc.
  966.  
  967.         minX,minY:  Minimum size of window.
  968.         maxX,maxY:  Maximum sixe of window.
  969.  
  970. A short example:
  971.  
  972.         REM 3.3.3 Window Limits.
  973.         DECLARE FUNCTION WindowLimits% LIBRARY
  974.         LIBRARY "intuition.library"
  975.         minX%=5
  976.         minY%=5
  977.         maxX%=640
  978.         maxY%=200
  979.         res%=WindowLimits(WINDOW(7),minX%,minY%,maxX%,maxY%)
  980.  
  981.         IF res% = 0 THEN
  982.                 PRINT "Something is incorrect ......."
  983.         END IF
  984.  
  985.         LIBRARY CLOSE
  986.         END
  987.  
  988.                 ---------------------------------------------
  989.  
  990. 3.3.4 SIZING WINDOWS.
  991.  
  992. The Intuition function SizeWindow is used to shrink or enlarge a window.
  993. SizeWindow requires three arguments:
  994.  
  995.         SizeWindow(window,deltaX,deltaY)
  996.  
  997.         window: Address of the window data structure.
  998.         deltaX: Number of pixels to enlarge the window horizontally 
  999.                 (negative = shrink)
  1000.         deltaY: Same action, only vertically.
  1001.  
  1002. This routine does not check for incorrect parameters. If your delta values
  1003. make the window smaller than is possible or bigger than the screen, you
  1004. will encounter a system crash. To prevent this, the next program has a
  1005. routine the recognises false values and makes them safe. This SUB is named
  1006. Size:
  1007.  
  1008.                                 PAGE 111
  1009.  
  1010. ------------------------------------------------------------------------------
  1011.  
  1012.         '############################################
  1013.         '#
  1014.         '# Section: 3.3.4
  1015.         '# Program: Window Limits.
  1016.         '# Date   : 04/10/87
  1017.         '# Author : tob.
  1018.         '# Version: 1.0
  1019.         '#
  1020.         '#############################################
  1021.  
  1022.         'Demonstrate setting a window's maximum and
  1023.         'and minimum settings.
  1024.  
  1025.         PRINT "Searching for .bmap file ......"
  1026.  
  1027.         'INTUITION-library
  1028.         'WindowLimits
  1029.  
  1030.         DECLARE FUNCTION WindowLimits% LIBRARY
  1031.  
  1032.         LIBRARY "intuition.library"
  1033.  
  1034.         demo:   CLS         
  1035.                 WINDOW 2,"Test Window",(10,10)-(400,100),16
  1036.                 WINDOW OUTPUT 2
  1037.  
  1038.                 '* Set window limits.
  1039.                 r% = WindowLimits%(WINDOW(7),0,0,600,200)
  1040.                 IF r% = 0 THEN ERROR 255
  1041.  
  1042.                 PRINT "Original Size - Please press a key .... "
  1043.                 WHILE INKEY$ = "": WEND
  1044.  
  1045.                 Size 60,40      '60 right, 40 down
  1046.                 PRINT "New size - press a key ......"
  1047.                 WHILE INKEY$ = "":WEND
  1048.  
  1049.                 Size -60,-40 ' 60 left, 40 up
  1050.                 PRINT "Restored!"
  1051.  
  1052.                 '* Wait
  1053.                 FOR t=1 TO 3000: NEXT t
  1054.  
  1055.                 '* Invalid arguments caught here
  1056.                 Size 10000,10000 ' Error
  1057.                 ' nothing happened thanks to the error check
  1058.  
  1059.                 WINDOW CLOSE 2
  1060.                 LIBRARY CLOSE
  1061.  
  1062.         SUB Size(x%,y%) STATIC
  1063.                 
  1064.                 win& =          WINDOW(7)
  1065.                 windo.width%    = PEEKW(win& + 8)
  1066.                 windo.height%   = PEEKW(win& + 10)
  1067.                 windo.minX%     = PEEKW(win& + 16)
  1068.                 windo.minY%     = PEEKW(win& + 18)
  1069.                 windo.maxX%     = PEEKW(win& + 20)
  1070.                 windo.maxY%     = PEEKW(win& + 22)
  1071.                 min.x%          = windo.minX%-windo.width%
  1072.                 min.y%          = windo.minY%-windo.height%
  1073.                 max.x%          = windo.maxX%-windo.width%
  1074.                 max.y%          = windo.maxY%-windo.height%
  1075.                 IF x%<min.x% OR x%>max.x% THEN x%=0
  1076.                 IF y%<min.y% OR y%>max.y% THEN y%=0
  1077.                 CALL SizeWindow(win&,x%,y%)
  1078.         END SUB
  1079.  
  1080.                                 PAGE 112
  1081.  
  1082. ----------------------------------------------------------------------------
  1083.  
  1084. 3.3.5 WINDOWTOFRONT AND WINDOWTOBACK.
  1085.  
  1086. A window can be moved to the background or foreground in relation to other
  1087. windows. These operations are normally performed with the mouse. However,
  1088. there are two intuition functions that can perform the same operation from
  1089. a program, WindowToFront and WindowToBack.
  1090.  
  1091. Here is a small demonstration:
  1092.  
  1093.         LIBRARY "intuition.library"
  1094.  
  1095.         FOR loop%= 1 TO 10
  1096.             CALL WindowToBack(WINDOW(7))
  1097.             PRINT "Behind!"
  1098.             FOR t = 1 TO 2000: NEXT t
  1099.             CALL WindowToFront(WINDOW(7))
  1100.             PRINT "In front!"
  1101.             FOR t = 1 TO 2000: NEXT t
  1102.         NEXT loop%
  1103.         END
  1104.  
  1105.                                 PAGE 113
  1106.  
  1107. ----------------------------------------------------------------------------
  1108.  
  1109. 3.4 THE INTUITION SCREEN.
  1110.  
  1111. Intuition also manages screens. An intuition screen data structure is
  1112. similar to those of intuition windows. The pointer to the screen data is
  1113. located at offset 46 in the window data structure. To obtain the base
  1114. address of your output window use the following:
  1115.  
  1116.         screen& = PEEKL(WINDOW(7)+46)
  1117.  
  1118. To calculate the address of an individual data field you add the offset to
  1119. the base address. The data structure is as follows:
  1120.  
  1121. Data structure Screen/Intuition/342 bytes.
  1122.  
  1123. Offset  Type    Description.
  1124. ------- ------- ---------------------------------------
  1125. +000    Long    Pointer to the next screen.
  1126. +004    Long    Pointer to the first window in this screen.
  1127. +008    Word    X coordinate of upper left corner.
  1128. +010    Word    Y coordinate of upper left corner.
  1129. +012    Word    Width of the screen.
  1130. +014    Word    Height of the screen.
  1131. +016    Word    Y coordinate of mouse pointer.
  1132. +018    Word    X coordinate of mouse pointer.
  1133. +020    Word    Flags
  1134.                 Bit 0  : 1 = Workbench screen.
  1135.                 Bit 0-3: 1 = Custom screen.
  1136.                 Bit 4  : 1 = Showtitle.
  1137.                 Bit 5  : 1 = Screen beeps now.
  1138.                 Bit 6  : 1 = Custom bit-map.
  1139. +022    Long    Pointer to screen name text.
  1140. +026    Long    Pointer to standard title text.
  1141. +030    Byte    TitleBar height.
  1142. +031    Byte    Vertical limit of titlebar.
  1143. +032    Byte    Horizontal limit of titlebar.
  1144. +033    Byte    Vertical limit of menus.
  1145. +034    Byte    Horizontal limit of menus.
  1146. +035    Byte    Top window border.
  1147. +036    Byte    Left window border.
  1148. +037    Byte    Right window border.
  1149. +038    Byte    Bottom window border.
  1150. +039    Byte    Unused.
  1151. +040    Long    Pointer to standard font TextAttr
  1152. +044     --     Viewport of screen.
  1153. +084     --     Rastport of screen.
  1154. +184     --     Bit-map of screen.
  1155. +224     --     LAyerInfo of screen.
  1156. +326    Long    Pointer to first screen gadget.
  1157. +330    Byte    DetailPen.
  1158. +331    Byte    BlockPen.
  1159. +332    Word    Backup register for Beep(), stores col0
  1160. +334    Long    Pointer to external data.
  1161. +338    Long    Pointer to user data.
  1162.  
  1163. You probably noticed that the window and screen data structures are quite
  1164. similar, even though some fields are new. Again, we will explain each field
  1165. individually.
  1166.  
  1167.                                 PAGE 114
  1168.  
  1169. ----------------------------------------------------------------------------
  1170.  
  1171. 3.4.1 SCREEN STRUCTURE.
  1172.  
  1173.  
  1174. OFFSET 0: NEXT SCREEN.
  1175.  
  1176. Screens are also organised by Intuition in the form of a data chain. When
  1177. there are other screens in a chain with your screen, the address of the
  1178. next screen's data block is at this offset.
  1179.  
  1180.  
  1181. OFFSET 4: FIRST WINDOW.
  1182.  
  1183. Remember the data chain used by windows: two fields, the father and child,
  1184. provide the address of the previous and next windows. By using these you
  1185. can move back and forth through the chain from one window to another.
  1186. however, this method has a small flaw. In order to go through the entire
  1187. chain, you have to find the beginning of the chain first. The active window
  1188. you access is not necessarily the first window in the chain.
  1189.  
  1190. If you are interested only in a window in a specific screen, there is an
  1191. easier method you can use. This field contains the address of the first
  1192. window data block. The address of the next window structure is in offset+0
  1193. of the window data structure.
  1194.  
  1195.         windo& = WINDOW(7)
  1196.         scr& = PEEKL(windo&+46)
  1197.         searcher&=scr&+4
  1198.         WHILE flag% = 0
  1199.             searcher& = PEEKL(searcher&)
  1200.             IF searcher& = 0 THEN
  1201.                 flag% = 1
  1202.             ELSE
  1203.                 counter%=counter%+1
  1204.                 PRINT "Window";counter%;
  1205.                 PRINT " Data block address : ";
  1206.                 PRINT searcher&
  1207.             END IF
  1208.         WEND
  1209.         END
  1210.  
  1211. NOTE: Although this method is easier to program, it only accesses those
  1212. windows in the output window of the current screen.
  1213.  
  1214.                                 PAGE 115
  1215.  
  1216. ----------------------------------------------------------------------------
  1217.  
  1218. OFFSET 8, 10, 12 AND 14: SCREEN DIMENSIONS.
  1219.  
  1220. Like the window structure, there offsets contain the coordinates of the
  1221. upper left hand corner of the screen and the height and width of the
  1222. screen. The corner coordinate is relative to the top corner of the
  1223. display. The current versions of the Amiga(500-2000) do not allow
  1224. horizontal shifting of the screen. Offset field +8 is available for future
  1225. compatibility.
  1226.  
  1227.  
  1228. OFFSET 16 AND 18: THE MOUSE COORDINATES.
  1229.  
  1230. Here you find the X and Y coordinates of the mouse pointer relative to the
  1231. upper left hand corner of the screen. During vertical screen movements the
  1232. Y value can vary a bit.
  1233.  
  1234.  
  1235. OFFSET 20: FLAGS.
  1236.  
  1237. The bit descriptions a self-explanatory. Show title means that the screen's
  1238. title text is visible. A custom bit-map is suitable when you are generating
  1239. a new screen that has its own drawing plane.
  1240.  
  1241.  
  1242. OFFSET 22 AND 26: THE NAME OF THE SCREEN.
  1243.  
  1244. This offset contains the address of either the name string of this screen
  1245. or a standard text string which is taken as default from a window when a
  1246. name string is not specified.
  1247.  
  1248.  
  1249. OFFSET 30-39: DEFAULT PARAMETERS.
  1250.  
  1251. These bytes contain various standard parameters, such as the dimensions
  1252. of the title bar etc.. All windows in this screen default to these
  1253. dimensions automatically.
  1254.  
  1255.  
  1256. OFFSET 40: THE STANDARD CHARACTER SET.
  1257.  
  1258. Whenever a window is opened in your screen, it has a standard character set
  1259. (a predetermined font). The address of this font is stored here.
  1260.  
  1261. We will be discussing character sets in more detail later.
  1262.  
  1263.                                 PAGE 116
  1264.  
  1265. ----------------------------------------------------------------------------
  1266.  
  1267. OFFSET 44 : THE VIEWPORT.
  1268.  
  1269. This is another new term we will be discussing in more detail later. In
  1270. relation to the data structure of the screen, the ViewPort is NOT a
  1271. pointer. At offset 44, it is the actual ViewPort of the screen. ViewPort,
  1272. which is a small data structure 40 bytes long, is an interface to the Amiga
  1273. graphic hardware (the COPPER graphic coprocessor).
  1274.  
  1275.  
  1276. OFFSET 84: THE RASTPORT.
  1277.  
  1278. This offset is not a pointer either but the actual RastPort. You received
  1279. an introduction to the RastPort in the window data structure. Since both
  1280. screen and windows are drawing planes, the screen also has a RastPort.
  1281.  
  1282.  
  1283. OFFSET 184: THE BIT-MAP.
  1284.  
  1285. This is a new data structure which is 40 bytes long. Bit-map is the
  1286. interface between the screen and the memory it occupies, called
  1287. "bit-planes".
  1288.  
  1289.  
  1290. OFFSET 234:THE LAYERINFO.
  1291.  
  1292. This is the last internal data structure of the screen. It is the core of
  1293. thw windowing system (the layers). This will be discussed in detail later.
  1294.  
  1295.  
  1296. OFFSET 326: POINTER TO SCREEN GADGETS.
  1297.  
  1298. Screens also recognise gadgets that move them to the background or bring
  1299. them to the foreground. This field is specifically for internal system use.
  1300.  
  1301.  
  1302. OFFSET 330 AND 331: THE SCREEN COLOURS.
  1303.  
  1304. Changing the screen colour values that are stored here works the same way
  1305. as for windows. The new colours take effect as soon as the screen is
  1306. refreshed, such as when you use a menu etc...
  1307.  
  1308.  
  1309. OFFSET 332: BACKUP-REGISTER.
  1310.  
  1311. Intuition stores the colour from register 0 here when the screen is flashed
  1312. or beeped. The following will beep the screen:
  1313.  
  1314.         PRINT CHR$(7)
  1315.  
  1316.  
  1317. OFFSET 334 AND 338: EXTERNAL AND USER DATA.
  1318.  
  1319. These allow the possibility to link other data blocks with the standard
  1320. structure.
  1321.  
  1322.                                 PAGE 117
  1323.  
  1324. ----------------------------------------------------------------------------
  1325.  
  1326. 3.4.2 THE INTUITION FUNCTIONS FOR SCREEN HANDLING.
  1327.  
  1328. Below are the routines from the intuition library used for screen handling:
  1329.  
  1330.         MoveScreen()
  1331.         ScreenToBack()
  1332.         ScreenToFront()
  1333.         WBenchToBack()
  1334.         WBenchToFront()
  1335.  
  1336. To make things easier we have written three SUBs that use all of these
  1337. routines. They are named ScrollScreen, ScreenHere and ScreenBye.
  1338.  
  1339. ScrollScreen requires the number of pixels that the screen should scroll
  1340. down in the current output window (a negative value scrolls it up).
  1341. ScreenBye sends the screen behind all current screens and ScreenHere brings
  1342. the screen to the foreground.
  1343.  
  1344. Here are the SUBs in a small demonstration program:
  1345.  
  1346.         '#####################################
  1347.         '#
  1348.         '# Section: 3.4.2
  1349.         '# Program: Screen Control.
  1350.         '# Date   : 01/04/87
  1351.         '# Author : tob
  1352.         '# Version: 1.0
  1353.         '#
  1354.         '######################################
  1355.  
  1356.         ' Program controlled screen handling.
  1357.  
  1358.         PRINT "Searching for .BMAP file ........."
  1359.  
  1360.         'INTUITION-library
  1361.         'MoveScreen()
  1362.         'ScreenToFront()
  1363.         'ScreenToBack()
  1364.  
  1365.         LIBRARY "intuition.library"
  1366.  
  1367.         init:   CLS
  1368.                 SCREEN 1,320,200,1,1
  1369.                 WINDOW 2,"Hello1",,,1
  1370.  
  1371.         main:   '* Screen scrolling.
  1372.                 PRINT "This is the second screen! "
  1373.                 
  1374.                                 
  1375.                                 PAGE 118
  1376.  
  1377. ----------------------------------------------------------------------------
  1378.  
  1379.         '* Screen 1 down.       
  1380.         WINDOW OUTPUT 2
  1381.         FOR loop% = 255 TO 0 STEP -1
  1382.             ScrollScreen(1)
  1383.         NEXT loop%
  1384.  
  1385.         '* Screen 0 Down.
  1386.         WINDOW OUTPUT 1
  1387.         FOR loop% = 255 TO 0 STEP -1
  1388.             ScrollScreen(1)
  1389.         NEXT loop%
  1390.  
  1391.         '* Screen 1 up.
  1392.         WINDOW OUTPUT 2
  1393.         FOR loop% = 0 TO 255
  1394.             ScrollScreen(-1)
  1395.         NEXT loop%
  1396.  
  1397.         '* Screen 0 up.
  1398.         WINDOW OUTPUT 1
  1399.         ScreenHere
  1400.         FOR loop% = 0 TO 255
  1401.             ScrollScreen(-1)
  1402.         NEXT loop%
  1403.         
  1404.         '* Swapping.
  1405.         FOR t% = 1 TO 3000:NEXT t%
  1406.         ScreenBye
  1407.         FOR t% = 1 TO 3000:NEXT t%
  1408.         ScreenHere
  1409.         FOR t% = 1 TO 3000:NEXT t%
  1410.         
  1411.         '* Closing.
  1412.         WINDOW CLOSE 2
  1413.         SCREEN CLOSE 1
  1414.  
  1415.         endprog:        LIBRARY CLOSE
  1416.                         END
  1417.  
  1418.         SUB ScrollScreen(pixel%) STATIC
  1419.                 screenAddress&=PEEKL(WINDOW(7)+46)
  1420.                 CALL MoveScreen(screenAddress&,0,pixel%)
  1421.         END SUB
  1422.  
  1423.         SUB ScreenHere STATIC
  1424.                 screenAddress& = PEEKL(WINDOW(7)+46)
  1425.                 CALL ScreenToFront(screenAddress&)
  1426.         END SUB
  1427.  
  1428.         SUB ScreenBye STATIC
  1429.                 screenAddress& = PEEKL(WINDOW(7)+46)
  1430.                 CALL ScreenToBack(screenAddress&)
  1431.         END SUB
  1432.  
  1433.                                 PAGE 119
  1434.  
  1435. ----------------------------------------------------------------------------
  1436.  
  1437. 3.5 INTUITION AND THE REST OF THE WORLD.
  1438.  
  1439. So far you have been introduced to the data structure of "windows" and
  1440. "screens". It is now time to for review amd show you the connections
  1441. between these two data blocks. The following figure symbolises a window
  1442. data structure to other components:
  1443.  
  1444.                                         |           |
  1445.                                         |           |
  1446.         ________________________________|___________|_____
  1447.        |                                |           |     |
  1448.        |                              Screen     Father   |
  1449.        |                                                  |
  1450.        |            W I N D O W                         __|____ next
  1451.        |                                                  |     window
  1452.        |        |                               |         |
  1453.        |        |                               |         |
  1454.        |________|_______________________________|_________|
  1455.                 |                               |
  1456.              RastPort                        Child Window.
  1457.         
  1458.  
  1459. The "screen" structure can be displayed using a similar figure:
  1460.  
  1461.  
  1462.         ____|__________________________________________
  1463.        |    |                                          |
  1464.        |  Next Screen                                  |
  1465.        |                                    1. window  |        
  1466.     ------- ViewPort    S C R E E N             ---------- 
  1467.        |                                               |
  1468.        |                                               |        
  1469.        |    |           |                              |
  1470.        |    |           |                              |
  1471.        |____|___________|______________________________|
  1472.             |           |
  1473.           BitMap      RastPort
  1474.  
  1475.                                 PAGE 120
  1476.  
  1477. ----------------------------------------------------------------------------
  1478.  
  1479. The next figure shows the system connection with a screen and a window:
  1480.  
  1481. NOTE: THE CHARACTER "+" REPRESENTS A DOWN ARROW.
  1482.  
  1483.  
  1484.         _________________________
  1485.        |                         |
  1486.        |                         |
  1487.      __|      S C R E E N        |<--------------------------------
  1488.     |  |                         |                                 |
  1489.     |  |                         |--------------------------       |
  1490.     |  |                         |                         |       |
  1491.     |  |_________________________|                         |       |
  1492.     |       |      |                                       |       |
  1493.     |       |      |                    ___________________+_______|__|_
  1494.     +       +      +                   |                              | |
  1495.  ViewPort  BitMap RastPort             |                                |
  1496.                                        |           W I N D O W        ----
  1497.                                        |                                |
  1498.                                        |                                |
  1499.                                        |___|__________________________|_|
  1500.                                            |                          | 
  1501.                                            +
  1502.                                         RastPort
  1503.  
  1504. We are not finished yet. You still need an understanding of the RastPort,
  1505. ViewPort and BitMap structures. Next we will take a closer look at the
  1506. RastPort.
  1507.  
  1508.                                 PAGE 121
  1509.  
  1510. ----------------------------------------------------------------------------
  1511.  
  1512. 3.6 THE RASTPORT.
  1513.  
  1514. With this data block, we get even closer to the basic elements of Amiga
  1515. graphics, the so called "graphic primitives". We'll leave intuition to go
  1516. deeper into the Amiga system architecture. We'll now explore the graphic
  1517. libraries.
  1518.  
  1519. The RastPort, which contains the data that controls how a drawing takes
  1520. place, manages a drawing plane. The starting address of the data block for
  1521. an actual window is always in the variable WINDOW(8). This address can be
  1522. read directly from the window data structure.
  1523.  
  1524.         PRINT WINDOW(8) 
  1525.         PRINT PEEKL(WINDOW(7)+50)
  1526.  
  1527. The RastPort structure is constructred as follows:
  1528.  
  1529. Data Structure: RastPort/Graphics/100 Bytes.
  1530.  
  1531. Offset  Type    Description.            
  1532. ------- ------- ------------------------------------------------------
  1533. +000    Long    Pointer to the layer structure.
  1534. +004    Long    Pointer to the Bit-map structure.
  1535. +008    Long    Pointer to the AreaFill pattern.
  1536. +012    Long    Pointer to the TmpRas structure.
  1537. +016    Long    Pointer to the AreaInfo structure.
  1538. +020    Long    Pointer to the GelsInfo structure.
  1539. +024    Byte    Mask: Writemask for this raster.
  1540. +025    Byte    Foreground colour.
  1541. +026    Byte    Background colour.
  1542. +027    Byte    AreaFill outline colour.
  1543. +028    Byte    Drawing mode:
  1544.                         JAM1            = 0
  1545.                         JAM2            = 1
  1546.                         COMPLEMENT      = 2
  1547.                         INVERSVID       = 4
  1548. +029    Byte    AreaPtSz: 2^n Words for AreaFill pattern.
  1549. +030    Byte    Unused.
  1550. +031    Byte    Line draw pattern preshift.
  1551. +032    Word    various control bits.
  1552.                 FIRST DOT       = 1 : Draw first pixel?
  1553.                 ONE DOT         = 2 : one dot mode for lines.
  1554.                 DBUFFER         = 4 : Double buffered set.
  1555. +034    Word    LinePtrn: 16 bits for line pattern.
  1556. +036    Word    X coordinate of graphic cursor.
  1557.  
  1558.                                 PAGE 122
  1559.  
  1560. ----------------------------------------------------------------------------
  1561.  
  1562. +038    Word    Y coordinate of graphic cursor.
  1563. +040    ----    8*1 byte minterms.
  1564. +048    Word    Cursor Width.
  1565. +050    Word    Cursor Height.
  1566. +052    Long    Pointer to character set.
  1567. +056    Byte    Character set mode (bold, italics etc...)
  1568. +057    Byte    textspecific flags.
  1569. +058    Word    Height of characterset.
  1570. +060    Word    Average character width.
  1571. +062    Word    Text height without underline.
  1572. +064    Word    Character spacing.
  1573. +066    Long    Pointer to user data.
  1574. +070    Word    Reserved (7x)
  1575. +084    Long    Reserved (2x)
  1576. +092    Byte    Reserved (8x)
  1577.  
  1578.                 ------------------------------------------
  1579.  
  1580. 3.6.1 THE RASTPORT STRUCTURE.
  1581.  
  1582. The following explains the RastPort structure by offset the same manner we
  1583. did for windows and screens:
  1584.  
  1585. OFFSET 0 : THE LAYER.
  1586.  
  1587. The Amiga uses layers to keep each drawing plane separate from the other
  1588. planes. These layers are actually the principle elements of each Intuition
  1589. window. You might think layers are very complicated and, compared to
  1590. windows, relatively useless. However, layers are important and a closer
  1591. look (as seen in a later chapter) will prove that they are really a
  1592. storehouse of graphic possibilities.
  1593.  
  1594.  
  1595. OFFSET 4: THE BITMAP.
  1596.  
  1597. You have already learned about the Bitmap, which is a pointer to the
  1598. bit-map structure. With this pointer you have indirect access to the screen
  1599. address through the RastPort:
  1600.  
  1601.         scr& = PEEKL(WINDOW(8)+4)-184
  1602.  
  1603. The bit-map is the intersection between the data structure and the RAM
  1604. banks where the window and screen contents are stored.
  1605.  
  1606.                                 PAGE 123
  1607.  
  1608. ----------------------------------------------------------------------------
  1609.  
  1610. OFFSET 8 : POINTER TO THE AREAFILL PATTERN.
  1611.  
  1612. You have seen how to fill areas with a single colour or with a pattern. If
  1613. you use a pattern, then that pattern has to be stored somewhere in memory.
  1614. This offset contains the address pointer to where the pattern is stored.
  1615.  
  1616. We will provide more information and examples after the offset
  1617. explanations. One of our subjects will show you how to use multi-colour
  1618. patterns of up to 32 colours.
  1619.  
  1620.  
  1621. OFFSET 12: THE TmpRas.
  1622.  
  1623. TmpRas stands for Temporary Raster. This is a pointer to an area of free
  1624. RAM used for certain operations. Whenever you use the fill commands like
  1625. PAINT or LINE BF, this RAM is used as a temporary holding area for the
  1626. entire object being filled.
  1627.  
  1628.  
  1629. OFFSET 16: AREA INFO.
  1630.  
  1631. This pointer is for a data structure used when drawing polygon shapes.
  1632. There is not much use for this from BASIC, but we will discuss it later.
  1633.  
  1634.  
  1635. OFFSET 20: GELSINFO.
  1636.  
  1637. Gels are Graphic Elements, such as sprites and Bobs (Blitter Objects), and
  1638. also the complete automatic Amiga animation system. Before this system can
  1639. be activated the GelsInfo structure has to be defined. This structure
  1640. contains some very important parameters.
  1641.  
  1642.  
  1643. OFFSET 24: WRITEMASK.
  1644.  
  1645. This variable allows individual bit-planes of the drawing plane to fade.
  1646. The default value is normally 255. All bits are set which means that all
  1647. available bit-planes are used. The POKE,
  1648.  
  1649.         POKE WINDOW(8) + 24,0
  1650.  
  1651. makes all bit-planes inactive and nothing more will be drawn on the
  1652. screen. You can also select specific bit planes to be active or inactive.
  1653.  
  1654.  
  1655. OFFSET 25,26 AND 27: DRAWING COLOUR.
  1656.  
  1657. These registers determine the drawing colours. The first contains the
  1658. number of the colour register for the drawing colour. The second has the
  1659. background and the third the AreaOutlineMode.
  1660.  
  1661.                                 PAGE 124
  1662.  
  1663. ------------------------------------------------------------------------------
  1664.  
  1665. OFFSET 28: DRAWING MODE.
  1666.  
  1667. The Amiga has four basic drawing modes that you can use. They are:
  1668.  
  1669.         JAM1            = 0
  1670.         JAM2            = 1
  1671.         COMPLEMENT      = 2
  1672.         INVERSEVID      = 4
  1673.  
  1674. The normal drawing mode is JAM2. This means that the foreground colour is
  1675. used to draw in the drawing plane and the rest will be in the background
  1676. colour. THe following example will make this clear:
  1677.  
  1678.         (Enter these examples in Direct Mode!)
  1679.         LINE (0,0)-(100,100),2,bf
  1680.         LOCATE 1,1:PRINT "hello!"
  1681.  
  1682. Thw white text appears on a blue background. A hole is made in the original
  1683. black background.
  1684.  
  1685. JAM 1 is different. The foreground colour is used to draw, but the
  1686. background is not changed.
  1687.         
  1688.         LINE (0,0)-(100,100),2,bf
  1689.         POKE WINDOW(8)+28,0
  1690.         LOCATE 1,1:PRINT "hello"
  1691.         POKE WINDOW(8)+28,1
  1692.  
  1693. COMPLEMENT complements the graphic with the background: Where ever a pixel
  1694. is set, it will be erased and just the opposite for unset pixels:
  1695.  
  1696.         LINE (0,0)-(100,100),2,bf
  1697.         POKE WINDOW(8)+28,2
  1698.         LINE(50,50)-(150,150),3,bf
  1699.         POKE WINDOW(8)+28,1
  1700.  
  1701. INVERSEVID inverts a graphicL background and foreground are exchanged. It
  1702. looks like this:
  1703.  
  1704.         POKE WINDOW(8)+28,4
  1705.         PRINT "Inverse!"
  1706.         POKE WINDOW(8)+28,1
  1707.  
  1708. These pokes work great in direct mode. However, they do not work in a
  1709. program. Nothing will happen.
  1710.  
  1711. The routine SetDrMd in the graphic library sets the desired mode safely and
  1712. reliably.
  1713.  
  1714.                                 PAGE 125
  1715.  
  1716. ----------------------------------------------------------------------------
  1717.  
  1718.         LIBRARY "graphic.library"
  1719.         CALL SetDrMd(WINDOW(8),mode%)
  1720.  
  1721.         mode% = 0 - 255
  1722.  
  1723. Various modes may be combined, only JAM1 and JAM2 work against each other.
  1724.  
  1725.  
  1726. OFFSET 29: AreaPtSz.
  1727.  
  1728. Whenever you work with patterns, you must specify how high the pattern will
  1729. be. Patterns can only be defined using powers of two (1,2,4,8,....). This
  1730. field stored the power of two.
  1731.  
  1732. Using a special programming method, you can use this register to activate
  1733. the mutli-colour pattern mode. This allows you to create patterns with up
  1734. to 32 colours. ( There will be more on this in the next section).
  1735.  
  1736.  
  1737. OFFSET 30,31 AND 32. FOR SYSTEM USE.
  1738.  
  1739. OFFSET 34: LINE PATTERN.
  1740.  
  1741. Patterns are not only for areas, but for lines also. The method is easy: 16
  1742. pixels in a row can be set or unset. The amiga then uses this Sample
  1743. pattern to draw lines. Take the following line pattern for example:
  1744.  
  1745.         *****.*.*****.*.
  1746.  
  1747. A dash dot dash dot line.
  1748.  
  1749. First you determine the bit values of the line:
  1750.  
  1751. bit& = 2^15+2^14+2^13+2^12+2^11+2^9+2^7+2^6+2^5+2^4+2^3+2^1
  1752.  
  1753. Now the value is stored to this register:
  1754.  
  1755.         POKEW WINDOW(8)+34,bit&
  1756.  
  1757. A test:
  1758.  
  1759.         LINE (10,10)-(600,10)
  1760.  
  1761. AS you can see it works.
  1762.  
  1763.  
  1764. OFFSET 36 AND 38: COORDINATES OF THE GRAPHIC CURSOR.
  1765.  
  1766. These two fields are extremely important. Text on the Amiga is nothing more
  1767. than text shaded graphics. Because of this, text can be placed in any
  1768. position on the screen. The following example demonstrates this:
  1769.  
  1770.         WHILE INKEY$ = ""
  1771.            x% = RND(1)*600
  1772.            y% = RND(1)*160
  1773.            POKEW WINDOW(8)+36,x%
  1774.            POKEW WINDOW(8)+38,y%
  1775.            PRINT "Commodore Amiga!"
  1776.         WEND
  1777.  
  1778.                                 PAGE 126
  1779.  
  1780. ----------------------------------------------------------------------------
  1781.  
  1782. OFFSET 40-51: MINTERMS, INTERNAL USAGE.
  1783.  
  1784. OFFSET 52: THE CHARACTER SET.
  1785.  
  1786. Just as in the screen structure this is a pointer to the currently active
  1787. font. The character set determines what your text looks like. We will
  1788. return to this subject later.
  1789.  
  1790.  
  1791. OFFSET 56: ACTUAL TEXT STYLE.
  1792.  
  1793. The Amiga can display a font in various forms on the screen:
  1794.         
  1795.         normal          = 0
  1796.         underlined      = Bit 0 set.
  1797.         bold            = Bit 1 set.
  1798.         italics         = Bit 2 set.
  1799.  
  1800. The last three modes can be combined to form different combinations.
  1801.  
  1802.  
  1803. OFFSET 57: TEXT FLAGS, INTERNAL USAGE.
  1804.  
  1805.  
  1806. OFFSET 58: TEXT HEIGHT.
  1807.  
  1808. This field contains the height of the currently active font. This value is
  1809. used to average the line height to calculate the correct line spacing.
  1810.  
  1811. There is nothing to prevent you from setting you own line spacing. It can
  1812. be even closer together than normal:
  1813.  
  1814.         POKEW WINDOW(8)+58,5
  1815.  
  1816. or further apart:
  1817.  
  1818.         POKEW WINDOW(8)+58,12
  1819.  
  1820.  
  1821. OFFSET 60: CHARACTER WIDTH.
  1822.  
  1823. This register contains the average width of the font. Since the Amiga also
  1824. supports proportional fonts (characters of different widths), you can set
  1825. the average width in this register.
  1826.  
  1827.                                 PAGE 127
  1828.  
  1829. ----------------------------------------------------------------------------
  1830.  
  1831. OFFSET 62: TEXT HEIGHT WITHOUT UNDERLINE.
  1832.  
  1833.  
  1834. OFFSET 64: CHARACTER SPACING.
  1835.  
  1836. The following routine allows you to vary the spacing between individual
  1837. characters. The default for this field is zero. Storing larger values here
  1838. will spread the characters over a larger area as in the following example:
  1839.  
  1840.         text$ = "Hello World!"
  1841.         text%=LEN(text$)
  1842.  
  1843.         FOR loop% = 1 TO 40
  1844.             POKEW WINDOW(8)+36,280-(loop%*text%*.5)
  1845.             '(centering)
  1846.             POKEW WINDOW(8)+38,90
  1847.             POKEW WINDOW(8)+64,loop%
  1848.             PRINT text$
  1849.         NEXT loop%
  1850.  
  1851.         FOR loop% = 39 TO 0 STEP -1
  1852.             POKEW WINDOW(8)+36,280-(loop%*text%*.5)
  1853.             POKEW WINDOW(8)+38,90
  1854.             POKEW WINDOW(8)+64,loop%
  1855.             PRINT text%
  1856.         NEXT loop%
  1857.  
  1858.         END
  1859.  
  1860.  
  1861. OFFSET 66: USER DATA.
  1862.  
  1863. This is a pointer to more data that can be linked to this structure.
  1864.  
  1865.  
  1866. OFFSET 70 to END - Reserved Data Fields.
  1867.  
  1868.                                 PAGE 128
  1869.  
  1870. ---------------------------------------------------------------------------- 
  1871.  
  1872. 3.7 GRAPHIC PRIMITIVES.
  1873.  
  1874. The RastPort provides us with the graphic primitives, which is the lowest
  1875. software controlled entry address to the graphic planes. First we will try
  1876. out a few of the possibilities of the RastPort that we have been
  1877. discussing.
  1878.  
  1879.                 ----------------------------------------------
  1880.  
  1881. 3.7.1 MULTICOLOUR PATTERNS.
  1882.  
  1883. At the beginning if the book we introduced you to the PATTERN statement.
  1884. Instead of having plain areas, you can use this statement to fill any
  1885. desired area with a pattern of your own design. 
  1886.  
  1887.         CIRCLE (310,100),100
  1888.         PAINT (310,100),2,1
  1889.  
  1890. We can also display patterned areas:
  1891.  
  1892.         DIM area.pat%(3)
  1893.         area.pat%(0)=&HFFFF
  1894.         area.pat%(1)=&HCCCC
  1895.         area.pat%(2)=&HCCCC
  1896.         area.pat%(3)=&HFFFF
  1897.  
  1898.         CIRCLE (310,100),100
  1899.         PATTERN ,area.pat%
  1900.         PAINT (310,100),3,1
  1901.  
  1902. You can see that this works, filling the circle with dotted orange pattern.
  1903. Up to now the patterns have been limited to one colour.
  1904.  
  1905. We have put together a complete pattern package that will enable you to
  1906. design and create your patterns and add more colour to them.
  1907.  
  1908. You know from the previous chapter that a pattern has to be stored in a
  1909. specific memory area. The height of the pattern is stored in the RastPort
  1910. field at Offset 29, as a power of two. Since we know the basics of
  1911. patterns, we can now write a small pattern SUB program to activate the
  1912. multicolour mode. This mode is switched on whenever the power at offset 29
  1913. is negative (a power of 256).
  1914.  
  1915.                                 PAGE 129
  1916.  
  1917. -----------------------------------------------------------------------------
  1918.  
  1919. The following program manages patterns without the PATTERN statement. It is
  1920. composed of these six routines:
  1921.  
  1922. 1.      InitPattern(howmany)%
  1923.  
  1924. This routine initialises our new pattern system. You pass the parameter for
  1925. how many lines high your example pattern is to be.
  1926.  
  1927. The routine calculates the required memory and calls GetMemory. The
  1928. starting address of the new buffer is form&.
  1929.  
  1930.  
  1931. 2.      SetPat(number%,pat$)
  1932.  
  1933. This new command allows you to easily enter the individual lines of your
  1934. pattern in a binary representation: An A equals an unset pixel and a B
  1935. equals a set pixel. The number% variable passes the row number of your
  1936. pattern and pat$ passes the actual bit pattern. Make sure that pat$ always
  1937. contains 16 characters. For a solid line pat$ would look like this:
  1938.  
  1939.                      "BBBBBBBBBBBBBBBB"
  1940.  
  1941.  
  1942. 3.      MonoPattern.
  1943.  
  1944. This routine is called without any arguments and activates the pattern
  1945. system. Both RastPort addresses are initialised to their correct values in
  1946. this routine.
  1947.  
  1948.  
  1949. 4.      EndPattern.
  1950.  
  1951. This routine is also called without any arguments. If tells the Amiga that
  1952. your example pattern will no longer be used. The memory used for your
  1953. pattern is released back to the system. You should call EndPattern at the
  1954. end of your program to release all memory back to the system.
  1955.  
  1956.  
  1957. 5.      GetMemory(size&).
  1958.  
  1959. This is an all purpose memory get routine. Whenever you need memory,
  1960. GetMemory gets it for you. You specify an & variable containing the amount
  1961. of memory you need in bytes.
  1962.  
  1963.  
  1964. 6.      
  1965.  
  1966. To reserve an area of 1245 bytes:
  1967.  
  1968.     DECLARE FUNCTION Allocmem& LIBRARY
  1969.     LIBRARY "exec.library"
  1970.  
  1971.     mymem& = 1245
  1972.     GetMemory mymem&
  1973.     PRINT "Starting address: ";mymem&
  1974.  
  1975. NOTE: If a value of zero is returned for the starting address the memory
  1976. allocation did not work. You did not receive a memory area and cannot use
  1977. FreeMemory to return it.
  1978.  
  1979.  
  1980. 6. FreeMemory(add&)
  1981.  
  1982. When you no longer require the memory that you have reserved you return it 
  1983. to the system with FreeMemory. A call to this routine looks like this:
  1984.  
  1985.     DECLARE FUNCTION AllocMem& LIBRARY
  1986.     LIBRARY "exec.library"
  1987.  
  1988.     form&=100 '100 bytes please!
  1989.     GetMemory form&
  1990.  
  1991.     (....)
  1992.  
  1993.     FreeMemory form& 'memory released.
  1994.     LIBRARY CLOSE
  1995.  
  1996. These six routines make working with patterns remarkably easy. Here are the
  1997. routines along with a small demonstration program.
  1998.  
  1999.     '###################################
  2000.     '#
  2001.     '# Section : 3.7.1a
  2002.     '# Program : Mono-pattern Module.
  2003.     '# Date    : 12/27/86
  2004.     '# Author  : tob
  2005.     '# Version : 1.0
  2006.     '#
  2007.     '#####################################
  2008.  
  2009.     'easy definition of modules using 
  2010.     'binary character strings.
  2011.  
  2012.     PRINT "Searching for .bmap file ....."
  2013.  
  2014.     'Exec library
  2015.     DECLARE FUNCTION AllocMem& LIBRARY
  2016.  
  2017.                 PAGE 131
  2018.  
  2019. ----------------------------------------------------------------------------
  2020.  
  2021.     'FREEMEM
  2022.  
  2023.     LIBRARY "exec.library"
  2024.  
  2025.     init:    'Activate system.
  2026.         CLS
  2027.         InitPattern 4
  2028.  
  2029.         'Set pattern.
  2030.         SetPat 0,"BBBBBBBBBBBBBBBB"
  2031.         SetPat 1,"BAAAAAAAAAAAAAAB"
  2032.         SetPat 2,"BAAAABBBBBBAAAAB"
  2033.         SetPat 3,"BAAAABBBBBBAAAAB"
  2034.  
  2035.         'Enable new pattern
  2036.         MonoPattern
  2037.  
  2038.         'Display Pattern on screen
  2039.         LINE (10,10)-(100,100),1,bf
  2040.         CIRCLE (300,100),100
  2041.         PAINT (300,100),2,1
  2042.  
  2043.         'Switch system back off
  2044.         EndPattern
  2045.  
  2046.     endprog: LIBRARY CLOSE
  2047.          END
  2048.  
  2049.     SUB InitPattern(howmany%) STATIC
  2050.         SHARED form&,plane1%,plane2%,kolor%
  2051.  
  2052.         '* is it a power of 2 ??
  2053.         IF LOG(howmany%)/LOG(2)<>INT(LOG(howmany%)/LOG(2) THEN
  2054.             PRINT "2^x! Power of two for InitPattern! 1,2,4,8,16.."
  2055.             ERROR 17
  2056.         END IF
  2057.  
  2058.         'Read PArameters.
  2059.         planes% = PEEK(PEEKL(WINDOW(8)+4)+5)    
  2060.         DIM SHARED p&(howmany%*planes%)
  2061.         plane1% = planes%
  2062.         plane2% = howmany%
  2063.         kolor% = 2^plane1%-1
  2064.  
  2065.         'Definition pattern Buffer allocate.
  2066.         form& = howmany%*2*planes%
  2067.         GetMemory form&
  2068.     END SUB
  2069.  
  2070.     SUB SetPat(number%,pat$) STATIC
  2071.         SHARED form&,plane1%,plane2%
  2072.  
  2073.         'Too many rows????
  2074.         IF number%>=plane2% THEN
  2075.             PRINT "More rows than you can define with InitPattern!"
  2076.             EndPattern
  2077.             ERROR 175
  2078.         END IF
  2079.  
  2080.                 PAGE 132
  2081.  
  2082. ----------------------------------------------------------------------------
  2083.  
  2084.         '* Error handling. Limit string to 16 bytes.
  2085.         IF LEN(pat$)<16 THEN
  2086.             pat$=pat$+STRING(16-LEN(pat$),"A")
  2087.         END IF
  2088.  
  2089.         'Read Definition pattern
  2090.         FOR loop1% = 0 TO 15
  2091.             check$ = UCASE$(MID$(pat$,loop1%+1,1)
  2092.             col% = ASC(check$)-65
  2093.             IF col%>=2^plane1% OR col%<0 THEN col% = 0
  2094.             FOR loop2% = col% TO 0 STEP -1
  2095.             IF col% >= 2^loop2% THEN
  2096.                 col% = = col%-2^loop2%
  2097.                 p&(number%+loop2%*plane2%) =
  2098.                    p&(number%+loop2%*plane2%)+2^(15-loop1%)
  2099.             END IF
  2100.             NEXT loop2%
  2101.         NEXT loop1%
  2102.  
  2103.         '* Write value to buffer
  2104.         FOR loop3% = 0 TO plane2%*plane1%
  2105.             POKEW form&+2*loop3%,p&(loop3%)
  2106.         NEXT loop3%
  2107.         END SUB
  2108.  
  2109.         SUB MonoPattern STATIC
  2110.         SHARED form&,plane2%
  2111.         planes% = LOG(planes2%)/LOG(2)
  2112.         POKEL WINDOW(8)+8,form&
  2113.         POKEL WINDOW(8)+29,planes%
  2114.         END SUB
  2115.  
  2116.         SUB EndPattern STATIC
  2117.          SHARED form&
  2118.  
  2119.         'Pattern off and release memory.
  2120.         POKEL WINDOW(8)+8,0
  2121.         POKE WINDOW(8)+29,0
  2122.         FreeMemory form&
  2123.         END SUB
  2124.  
  2125.         SUB GetMemory(size&) STATIC
  2126.         mem.opt& = 2^0+2^1+2^16
  2127.         RealSize& = size&+4
  2128.         size& = AllocMem&(RealSize&,opt&)
  2129.         IF size& = 0 THEN ERROR 255
  2130.         POKEL size&,RealSize&
  2131.         size& = size& + 4
  2132.         END SUB
  2133.  
  2134.                 PAGE 133
  2135.  
  2136. -----------------------------------------------------------------------------
  2137.     
  2138.     SUB FreeMemory(add&) STATIC
  2139.         add& = add& - 4
  2140.         RealSize& = PEEKL(add&)
  2141.         CALL FreeMem(add&,RealSize)
  2142.     END SUB
  2143.  
  2144. So far our SUB programs do not provide colour patterns. To fix this we will 
  2145. add the routine ColorPattern to our program. If replaces MonoPattern and 
  2146. activated the multicolor system. Depending on your screen depth, you can
  2147. use up to 32 colors in your patterns. Additional characters are available now
  2148. for defining your patterns:
  2149.  
  2150.     Color 1    A Color Register 0 (background)    
  2151.     Color 2       B Color Register 1 
  2152.     Color 3       C Color Register 2
  2153.     Color 4       D Color Register 3
  2154.     (for the workbench screen)
  2155.  
  2156. The following program demonstrates multi-colour patterns.
  2157.  
  2158.     '############################
  2159.     '#
  2160.     '# Section: 3.7.1b
  2161.     '# Program: Mono &Colour pattern.
  2162.     '# Date   : 12/27/86
  2163.     '# Author : tob
  2164.     '# Version: 1.0
  2165.     '#
  2166.     '##############################
  2167.     
  2168.  
  2169.     'Makes "multi-colour" patterns possible.
  2170.     'Via RastPort manipulation.
  2171.  
  2172.     PRINT "Searching for .bmap file ......."
  2173.  
  2174.     'EXEC library
  2175.     'DECLARE FUNCTION AllocMem& LIBRARY
  2176.     'FreeMem()
  2177.  
  2178.     LIBRARY "exec.library"
  2179.     
  2180.     init:    CLS
  2181.         rows%=8
  2182.         InitPattern rows%
  2183.         '         0123456789ABCDEF'
  2184.         SetPat 0,"DCDAAAAAAABBAAAA"
  2185.         SetPat 1,"DCDAAAAAABBBBAAA"
  2186.         SetPat 2,"DCDAAAAABAABBAAA"
  2187.         SetPat 3,"DCDAAAABAAAABBAA"
  2188.         SetPat 4,"DCDAAABBBBBBBBBA"
  2189.         SetPat 5,"DCDAABAAAAAAABBA"
  2190.         SetPat 6,"DCDBBBBAAAAABBBB"
  2191.         SetPat 7,"CCCCCCCCCCCCCCCC"
  2192.  
  2193.                 PAGE 134
  2194.  
  2195. ----------------------------------------------------------------------------
  2196.  
  2197.     drawing:PRINT TAB(7);"MONO";TAB(36);"COLOR!"
  2198.  
  2199.         MonoPattern
  2200.         CIRCLE (60,60),60
  2201.         PAINT (60,60),kolor%,1
  2202.  
  2203.         ColorPattern
  2204.         CIRCLE (310,100),100
  2205.         PAINT (310,100),kolor%,1
  2206.  
  2207.     endprog:EndPattern
  2208.         LIBRARY CLOSE
  2209.         END
  2210.  
  2211.     SUB ColorPattern STATIC
  2212.         SHARED form&,plane2%
  2213.         planes% = LOG(plane2%)/LOG(2)
  2214.         POKEL WINDOW(8)+8,form&
  2215.         POKE WINDOW(8)+29,256-planes%
  2216.     END SUB
  2217.  
  2218.     SUB InitPattern(howmany%) STATIC
  2219.         SHARED form&,plane1%,plane2%,kolor%
  2220.  
  2221.         'Is it a power of two ???
  2222.         IF LOG(howmany%)/LOG(2)<>INT(LOG(howmany%)/LOG(2)) THEN
  2223.             PRINT "2^x! A power of two for initpattern! 1,2,4,8,16"
  2224.             ERROR 17
  2225.         END IF
  2226.  
  2227.         '* Read parameters.
  2228.         planes% = PEEK(PEEKL(WINDOW(8)+4)+5)
  2229.         DIM SHARED p&(howmany%*planes%)
  2230.         plane1% = planes%
  2231.         plane2% = howmany%
  2232.         kolor% = 2^plane1%-1
  2233.  
  2234.         '* Reserve definition pattern buffer.
  2235.         form& = howmany%*2*planes%
  2236.         GetMemory form&
  2237.     END SUB
  2238.  
  2239.     SUB SetPat(number%,pat$) STATIC
  2240.         SHARED form&,plane1%,plane2%
  2241.  
  2242.         'Too many rows?
  2243.         IF number%>=plane2% THEN
  2244.             PRINT "More rows than can be defined with InitPattern!"
  2245.             EndPattern
  2246.             ERROR 17
  2247.         END IF
  2248.  
  2249.                 PAGE 135
  2250.  
  2251. ------------------------------------------------------------------------------
  2252.  
  2253.         '* Error-handling: Limit string to 16 bytes,
  2254.         IF LEN(pat$)<16 THEN
  2255.             pat$=pat$+STRING$(16-LEN(pat$),"A")
  2256.         END IF
  2257.  
  2258.         '* Read Pattern Definition.
  2259.         FOR loop1% = 0 TO 15
  2260.             check$ = UCASE$(MID$(pat$,loop1%+1,1))
  2261.             col% = ASC(check$)-65
  2262.             IF col%>=2^plane1% OR col1%<0 THEN col% = 0
  2263.             FOR loop2% = col% TO 0 STEP -1
  2264.             IF col%>=2^loop2% THEN
  2265.                 col% = col%-2^loop2%
  2266.                 p&(number%+loop2%*plane2%) =
  2267.                    p&(numer%,+loop2%*plane2%)+2^(15-loop1%)
  2268.             END IF
  2269.             NEXT loop2%
  2270.         NEXT loop1%
  2271.  
  2272.         '* Write value to buffer.
  2273.         FOR loop3% = 0 TO plane2%*plane1%
  2274.             POKEW form&+2*loop3%,p&(loop3%)
  2275.         NEXT loop3%
  2276.     END SUB
  2277.     
  2278.     SUB MonoPattern STATIC
  2279.         SHARED form&,plane2%
  2280.         planes% = LOG(plane2%)/LOG(2)
  2281.         POKEL WINDOW(8)+8, form&
  2282.         POKE WINDOW(8)+29, planes%
  2283.     END SUB
  2284.  
  2285.     SUB EndPattern STATIC
  2286.         SHARED form&
  2287.  
  2288.         '*Pattern off and release memory.
  2289.         POKEL WINDOW(8)+8,0    
  2290.         POKEW WINDOW(8)+29,0    
  2291.         FreeMemory form&
  2292.     END SUB
  2293.  
  2294.     SUB GetMemory(size&) STATIC
  2295.         mem.opt& = 2^0+2^1+2^16
  2296.         RealSize&= size&+4
  2297.         size& = AllocMem&(RealSize&,opt&)
  2298.         IF size& = 0 THEN ERROR 255
  2299.         POKEL size&,RealSize&
  2300.         size& = size&+4
  2301.     END SUB
  2302.  
  2303.     SUB FreeMemory(add&) STATIC
  2304.         add& = add&-4
  2305.         RealSize& = PEEKL(add&)
  2306.         Call FreeMem(add&,RealSize&)
  2307.     END SUB
  2308.  
  2309.                 PAGE 136
  2310.  
  2311. ----------------------------------------------------------------------------
  2312.  
  2313. If the four workbench screens are not enough, you can create your own 
  2314. screens with more than 2 bit-planes. The following program does just this.
  2315. After the initialisation you will see, as a fill pattern, a familiar logo
  2316. in 11 colors. If you hold down the left mouse button you can draw using this
  2317. pattern.
  2318.  
  2319.  
  2320.     '############################
  2321.     '#
  2322.     '# Section: 3.7.1c
  2323.     '# Program: Multi-Colour-Pattern
  2324.     '# Date   : 12/27/86
  2325.     '# Author : tob
  2326.     '# Version: 1.0
  2327.     '#
  2328.     '##############################
  2329.     
  2330.     'Demonstrates the use of a multi-colour pattern with 
  2331.     ' up to 16 Colors (Screen Depth = 4), ; up to 32 colours
  2332.     ' possible.
  2333.     'Color value: A=0 to Z=25, Colors 26-32 = chr$(91)-chr$(97)
  2334.     ' On "out of heap space" close other window!
  2335.  
  2336.     PRINT "Searching for .bmap file ......."
  2337.  
  2338.     'EXEC library
  2339.     'DECLARE FUNCTION AllocMem& LIBRARY
  2340.     'FreeMem()
  2341.  
  2342.     LIBRARY "exec.library"
  2343.     
  2344.     init:    SCREEN 1,640,200,4,2
  2345.         WINDOW 1,"Hello!",,,1        
  2346.  
  2347.         LOCATE 4,15
  2348.         PRINT "** Patience ! **"
  2349.  
  2350.         rows%=8
  2351.         InitPattern rows%
  2352.         '         0123456789ABCDEF'
  2353.         SetPat 0,"AAAAAAAAAAABBABB"
  2354.         SetPat 1,"AAAAAAAAAABBABBA"
  2355.         SetPat 2,"AAAAAAAAACCACCAA"
  2356.         SetPat 3,"AAAAAAAADDADDAAA"
  2357.         SetPat 4,"FFAFFAAEEAEEAAAA"
  2358.         SetPat 5,"AGGAGGHHAHHAAAAA"
  2359.         SetPat 6,"AAKKAIIAIIAAAAAA"
  2360.         SetPat 7,"AAAJJJJJJAAAAAAA"
  2361.  
  2362.                 PAGE 137
  2363.  
  2364. ----------------------------------------------------------------------------
  2365.  
  2366.     patcol:    '* Colour choices for the pattern.
  2367.         PALETTE 0,0,0,0        'A
  2368.         PALETTE 1,.9,.3,.4    'B
  2369.         PALETTE 2,.8,.5,.4    'C
  2370.         PALETTE    3,.8,.6,0    'D
  2371.         PALETTE    4,1,.8,0    'E
  2372.         PALETTE 5,0,0,.6    'F
  2373.         PALETTE 6,0,.3,.6    'G
  2374.         PALETTE 7,.7,.9,0    'H
  2375.         PALETTE 8,.3,.9,0    'I
  2376.         PALETTE 9,0,.5,0    'J
  2377.         PALETTE 10,0,.3,0!    'K
  2378.  
  2379.  
  2380.     drawing:ColorPattern
  2381.         LOCATE (3,10)
  2382.  
  2383.         PRINT "Press Left mouse button to draw"
  2384.         PRINT TAB(10);"Touch left screen border to exit."    
  2385.         CIRCLE (310,100),100
  2386.         PAINT (310,100),kolor%,1
  2387.  
  2388.  
  2389.     mousecontr:test% = MOUSE(0)
  2390.         WHILE MOUSE(1)<>0
  2391.             x%=MOUSE(1)
  2392.             y%=MOUSE(2)
  2393.             IF test%<>0 THEN
  2394.             LINE (x%,y%)-(x%+10,y%+5),kolor%,bf
  2395.             END IF
  2396.             test% = MOUSE(0)
  2397.         WEND
  2398.  
  2399.  
  2400.     endprog:EndPattern
  2401.         WINDOW 1,"Demo Over !!!",,,-1
  2402.         LIBRARY CLOSE
  2403.         END
  2404.  
  2405.  
  2406.     SUB ColorPattern STATIC
  2407.         SHARED form&,plane2%
  2408.         planes% = LOG(plane2%)/LOG(2)
  2409.         POKEL WINDOW(8)+8,form&
  2410.         POKE WINDOW(8)+29,256-planes%
  2411.     END SUB
  2412.  
  2413.     SUB InitPattern(howmany%) STATIC
  2414.         SHARED form&,plane1%,plane2%,kolor%
  2415.  
  2416.         'Is it a power of two ???
  2417.         IF LOG(howmany%)/LOG(2)<>INT(LOG(howmany%)/LOG(2)) THEN
  2418.             PRINT "2^x! A power of two for initpattern! 1,2,4,8,16"
  2419.             ERROR 17
  2420.         END IF
  2421.  
  2422.                 PAGE 138
  2423.  
  2424. ----------------------------------------------------------------------------
  2425.  
  2426.         '* Read parameters.
  2427.         planes% = PEEK(PEEKL(WINDOW(8)+4)+5)
  2428.         DIM SHARED p&(howmany%*planes%)
  2429.         plane1% = planes%
  2430.         plane2% = howmany%
  2431.         kolor% = 2^plane1%-1
  2432.  
  2433.         '* Reserve definition pattern buffer.
  2434.         form& = howmany%*2*planes%
  2435.         GetMemory form&
  2436.     END SUB
  2437.  
  2438.     SUB SetPat(number%,pat$) STATIC
  2439.         SHARED form&,plane1%,plane2%
  2440.  
  2441.         'Too many rows?
  2442.         IF number%>=plane2% THEN
  2443.             PRINT "More rows than can be defined with InitPattern!"
  2444.             EndPattern
  2445.             ERROR 17
  2446.         END IF
  2447.  
  2448.  
  2449.         '* Error-handling: Limit string to 16 bytes,
  2450.         IF LEN(pat$)<16 THEN
  2451.             pat$=pat$+STRING$(16-LEN(pat$),"A")
  2452.         END IF
  2453.  
  2454.         '* Read Pattern Definition.
  2455.         FOR loop1% = 0 TO 15
  2456.             check$ = UCASE$(MID$(pat$,loop1%+1,1))
  2457.             col% = ASC(check$)-65
  2458.             IF col%>=2^plane1% OR col1%<0 THEN col% = 0
  2459.             FOR loop2% = col% TO 0 STEP -1
  2460.             IF col%>=2^loop2% THEN
  2461.                 col% = col%-2^loop2%
  2462.                 p&(number%+loop2%*plane2%) =
  2463.                    p&(numer%,+loop2%*plane2%)+2^(15-loop1%)
  2464.             END IF
  2465.             NEXT loop2%
  2466.         NEXT loop1%
  2467.  
  2468.         '* Write value to buffer.
  2469.         FOR loop3% = 0 TO plane2%*plane1%
  2470.             POKEW form&+2*loop3%,p&(loop3%)
  2471.         NEXT loop3%
  2472.     END SUB
  2473.     
  2474.     SUB MonoPattern STATIC
  2475.         SHARED form&,plane2%
  2476.         planes% = LOG(plane2%)/LOG(2)
  2477.         POKEL WINDOW(8)+8, form&
  2478.         POKE WINDOW(8)+29, planes%
  2479.     END SUB
  2480.  
  2481.  
  2482.                 PAGE 139
  2483.  
  2484. ----------------------------------------------------------------------------
  2485.  
  2486.     SUB EndPattern STATIC
  2487.         SHARED form&
  2488.  
  2489.         '*Pattern off and release memory.
  2490.         POKEL WINDOW(8)+8,0    
  2491.         POKEW WINDOW(8)+29,0    
  2492.         FreeMemory form&
  2493.     END SUB
  2494.  
  2495.     SUB GetMemory(size&) STATIC
  2496.         mem.opt& = 2^0+2^1+2^16
  2497.         RealSize&= size&+4
  2498.         size& = AllocMem&(RealSize&,opt&)
  2499.         IF size& = 0 THEN ERROR 255
  2500.         POKEL size&,RealSize&
  2501.         size& = size&+4
  2502.     END SUB
  2503.  
  2504.     SUB FreeMemory(add&) STATIC
  2505.         add& = add&-4
  2506.         RealSize& = PEEKL(add&)
  2507.         Call FreeMem(add&,RealSize&)
  2508.     END SUB
  2509.  
  2510.         ----------------------------------------------------
  2511.  
  2512. 3.7.2 SHADOWS USING CURSOR POSITIONING.
  2513.  
  2514. The multi-coloured patterns in the last section were created by skillfully
  2515. manipulating the rastports. With some creativity you can do a lot more with 
  2516. these data structures. To demonstrate this we will show you what can be done
  2517. with a little help from offset fields 28,36 and 38.
  2518.  
  2519. These fields manage:
  2520.  
  2521. Offset    Type    Description
  2522. ------- ------- ---------------------------------------
  2523. +028    Byte    Drawing modes:
  2524.         JAM1        = 0
  2525.         JAM2        = 1
  2526.         COMPLEMENT    = 2
  2527.          INVERSE VID    = 4
  2528.  
  2529. +036    Word    Coordinate of graphic cursor.
  2530. +038    Word    Coordinate of graphic cursor.
  2531.  
  2532. With these offsets we will create a shadowed text effect. You may have seen 
  2533. this method on television, which has used it for a long time. First the 
  2534. text is printed in black, then the text is printed again in white over the 
  2535. black but slightly offset. This creates a shadow effect that makes the text
  2536. visibly stand out. It doesnt matter if the background is dark or light, the
  2537. contrast is still visible.
  2538.  
  2539.                 PAGE 140
  2540.  
  2541. ----------------------------------------------------------------------------
  2542.  
  2543. We will use three routines from the graphic library to create our effect:
  2544.  
  2545.     SetDrMd()
  2546.     Text()
  2547.     Move()
  2548.  
  2549. The first routine, SetDrMd(), sets the drawing mode and directly affects 
  2550. RastPort offset 28, (see section 3.6.1). The text routine Text(), which
  2551. was discussed in chapter 2, prints text on the screen. The move routine 
  2552. Move(), puts the graphic cursor at a selected position and affects Rastport
  2553. offsets 36 and 38. Instead of using the Move() routine, you could poke the
  2554. values into the memory offsets.
  2555.  
  2556. Our routine is named "shadows" and it requires two arguments:
  2557.  
  2558.     Shadow text$,mode%
  2559.  
  2560.     text$:    The text that is to be displayed.
  2561.     mode%:    0 = PRINT text$
  2562.         1 = PRINT text$;
  2563.  
  2564.     Here is the program:
  2565.  
  2566.     '#########################################    
  2567.     '#
  2568.     '# Section : 3.7.2
  2569.     '# Program : Shadow Print.
  2570.     '# Datum   : 12/25/86
  2571.     '# Author  : tob
  2572.     '# Version : 1.0
  2573.     '#
  2574.     '###########################################
  2575.  
  2576.     PRINT "Searching for .bmap file ....."
  2577.  
  2578.     'GRAPHICS-Library
  2579.     'Text()
  2580.     'Move()
  2581.     'SetDrMd()
  2582.  
  2583.     LIBRARY "graphics.library"
  2584.  
  2585.     main:     '* Contrast color
  2586.         PALETTE 0,.5,.5,.5
  2587.         CLS
  2588.         LOCATE 5,1
  2589.         PRINT "This is normal text without contrast."
  2590.         PRINT "Not very exciting ....."        
  2591.  
  2592.                 PAGE 141
  2593.  
  2594. -----------------------------------------------------------------------------
  2595.  
  2596.         PRINT 
  2597.         Shadow "Shadow print is just a fast as print !",0
  2598.         Shadow "It works due to the actions of the ",0
  2599.         Shadow "Text() function of the Graphic-Library",0
  2600.         PRINT
  2601.         Shadow "The text effectively appears to float",0
  2602.         Shadow "in FRONT of the screen.",0
  2603.  
  2604.     endprog: LIBRARY CLOSE
  2605.          END
  2606.  
  2607.     SUB Shadow(Text$,mode%) STATIC
  2608.  
  2609.         '* Lock in parameters.
  2610.         textlen% = LEN(Text$)
  2611.         depth% = 2
  2612.         cx% = PEEKW(WINDOW(8)+36)
  2613.         cy% = PEEKW(WINDOW(8)+38)
  2614.  
  2615.         '* Draw shadows.
  2616.         COLOR 2,0
  2617.         CALL Move(WINDOW(8),cx%+depth%,cy%+depth%)
  2618.         CALL Text(WINDOW(8),SADD(Text$),textlen%)
  2619.  
  2620.         '* Draw JAM1 and Foreground.
  2621.         CALL SetDrMd(WINDOW(8),0)
  2622.         COLOR 0M2
  2623.         CALL Move(WINDOW(8),cX%,cY%)
  2624.         CALL Text(WINDOW(8),SADD(Text$),textlen%)
  2625.  
  2626.         '* CR as desired.
  2627.         IF mode% = 0 THEN
  2628.             PRINT
  2629.         END IF
  2630.  
  2631.         '* And again with JAM2 and finish.
  2632.         CALL SetDrMd(WINDOW(8),1)
  2633.     END SUB
  2634.  
  2635. During the drawing process it is necessary to switch the drawing mode from
  2636. JAM2 to JAM1. Otherwise the white text would completely cover the black 
  2637. text.
  2638.  
  2639. We use the Text() function instead of the PRINT statement to gain more speed
  2640. . Text() is more than 3 times faster than PRINT. This is why our shadow
  2641. text is displayed faster than the normal text. To see the difference just
  2642. switch the lines around:
  2643.  
  2644.     CALL Text(WINDOW(8),SADD(text$),textlen%)
  2645.  
  2646. for the line:
  2647.         
  2648.     PRINT text$
  2649.  
  2650. The difference in speed is enormous.
  2651.  
  2652.         ----------------------------------------------
  2653.  
  2654. 3.7.3 OUTLINE PRINT - A SPECIAL FLAIR.
  2655.  
  2656. This type of text displays only the silhouette of the characters. It 
  2657. quickly catches the eye and is especially useful for creating titles.
  2658.  
  2659. You can access this mode by using the following technique. The text is 
  2660. output using the drawing mode JAM1 and, while being displayed, is moved
  2661. one pixel in all directions. The result is a smeared character. Now the 
  2662. text is output again in the original position using the background color.
  2663. The final result is a silhouette of a character.
  2664.  
  2665. Here is a routine named OUTLINE which is very similar to the previous 
  2666. shadow routine.
  2667.  
  2668.  
  2669.     '#########################################    
  2670.     '#
  2671.     '# Section : 3.7.3
  2672.     '# Program : Outlne Print.
  2673.     '# Datum   : 12/25/86
  2674.     '# Author  : tob
  2675.     '# Version : 1.0
  2676.     '#
  2677.     '###########################################
  2678.  
  2679.     PRINT "Searching for .bmap file ....."
  2680.  
  2681.     'GRAPHICS-Library
  2682.     'Text()
  2683.     'Move()
  2684.     'SetDrMd()
  2685.  
  2686.     LIBRARY "graphics.library"
  2687.  
  2688.     main:     CLS
  2689.         LOCATE 5,1
  2690.         Outline " OUTLINE PRINT stands out and catches the eye!",0
  2691.         Outline " Although the drawing process is complicated, ",0
  2692.         Outline "it is extremely fast due to the Text() function",0
  2693.         Outline "Outline will also work with other character sets",0
  2694.  
  2695.     endprog: LIBRARY CLOSE
  2696.          END
  2697.  
  2698.                 PAGE 144
  2699.  
  2700. ----------------------------------------------------------------------------
  2701.  
  2702.     SUB Outline(Text$,mode%) STATIC
  2703.  
  2704.         '* Lock in parameters.
  2705.         textlen% = LEN(Text$)
  2706.         cx% = PEEKW(WINDOW(8)+36)
  2707.         cy% = PEEKW(WINDOW(8)+38)
  2708.  
  2709.         '* JAM1 and smear text.
  2710.         '* A loop is faster and more effective.
  2711.         CALL SetDrMd(WINDOW(8),0)
  2712.         CALL Move(WINDOW(8),cx%+1,cy%)
  2713.         CALL Text(WINDOW(8),SADD(Text$),textlen%)
  2714.         CALL Move(WINDOW(8),cx%-1,cy%)
  2715.         CALL Text(WINDOW(8),SADD(text$),textlen%)
  2716.         CALL Move(WINDOW(8),cx%,cy%+1)
  2717.         CALL Text(WINDOW(8),SADD(Text$),textlen%)
  2718.         CALL Move(WINDOW(8),cx%,cy%-1)
  2719.         CALL Text(WINDOW(8),SADD(text$),textlen%)        
  2720.         CALL Move(WINDOW(8),cx%-1,cy%-1)
  2721.         CALL Text(WINDOW(8),SADD(Text$),textlen%)
  2722.         CALL Move(WINDOW(8),cx%+1,cy%+1)
  2723.         CALL Text(WINDOW(8),SADD(text$),textlen%)
  2724.         CALL Move(WINDOW(8),cx%+1,cy%-1)
  2725.         CALL Text(WINDOW(8),SADD(Text$),textlen%)
  2726.         CALL Move(WINDOW(8),cx%-1,cy%+1)
  2727.         CALL Text(WINDOW(8),SADD(text$),textlen%)
  2728.  
  2729.         '* Background colour and hollow text.
  2730.         COLOR 0,0
  2731.         CALL Move(WINDOW(8),cx%,cy%)
  2732.         CALL Text(WINDOW(8),SADD(text$),textlen%)
  2733.  
  2734.         '* Reset Modes and colour, CR as needed
  2735.         COLOR 1,0
  2736.         IF mode%=0 THEN
  2737.             PRINT
  2738.         END IF
  2739.         CALL SetDrMd(WINDOW(8),1)
  2740.     END SUB
  2741.  
  2742.         --------------------------------------------------
  2743.  
  2744. 3.7.4 TEXT STYLES
  2745.  
  2746. The four different text styles of the Amiga can be program controlled. The 
  2747. value stored at RastPort offset 56 controls how the Amiga displays the text.
  2748.  
  2749.                 PAGE 144
  2750.  
  2751. ----------------------------------------------------------------------------
  2752.  
  2753.         A.) normal
  2754.         B.) BOLD
  2755.         C.) underlined.
  2756.         D.) Italics.
  2757.  
  2758. In addition to these, you can combine the styles. These are basically two
  2759. ways to switch between these styles:
  2760.  
  2761. A.) Direct RastPort Manipulation.
  2762.  
  2763.     With this method you POKE directly to the RastPort to switch. It works
  2764.     like this:
  2765.  
  2766.         normal% = 0
  2767.         underline% = 2^0
  2768.         bold% = 2^1
  2769.         italic% = 2^2
  2770.  
  2771.         POKE WINDOW(8)+56,underline%
  2772.         PRINT "Underlined text"
  2773.  
  2774.         POKE WINDOW(8)+56,bold%
  2775.         PRINT "Bold Text"
  2776.  
  2777.         POKE WINDOW(8)+56,italic%+underline%
  2778.         PRINT "Combined: Italic and Underlined"
  2779.  
  2780.         POKE WINDOW(8)+56,normal%
  2781.  
  2782. b.) Via graphic libraries:
  2783.  
  2784. The library has two functions that handle text styles:
  2785.  
  2786.     AskSoftStyle() and SetSoftStyle()
  2787.  
  2788. The principle is similar. Again the four types are available and can be 
  2789. mixed. The call to SetSoftStyle requires a third parameter:
  2790.  
  2791.     newStyle% = SetSoftStyle%(RastPort,mode,enable)
  2792.  
  2793.     RastPort :    Address of RastPort.
  2794.     mode     :    The desired style.
  2795.     enable   :    The available styles.
  2796.  
  2797. If is possible that a font won't be compatible with a specific style and 
  2798. therefore, will not be legible. To prevent this, the graphic library 
  2799. provides the enable field. The AskSoftStyle function checks a mask that 
  2800. returns all the legal styles available for the current font. This value
  2801. is then returned to SetSoftStyle. Here is a sample program:
  2802.  
  2803.                 PAGE 145
  2804.  
  2805. ----------------------------------------------------------------------------
  2806.  
  2807.     '##################################
  2808.     '#
  2809.     '# Section : 3.7.4
  2810.     '# Program : SoftStyle.
  2811.     '# Date    : 12/20/86
  2812.     '# Author  : tob
  2813.     '# Version : 1.0
  2814.     '#
  2815.     '####################################
  2816.  
  2817.     ' Demonstrates the use of different text styles
  2818.     ' named 'softstyles' that are software controlled.
  2819.  
  2820.     PRINT "Searching for .bmap file .........."
  2821.  
  2822.     'GRAPHICS LIBRARY
  2823.     DECLARE FUNCTION AskSoftStyle& LIBRARY
  2824.     DECLARE FUNCTION SetSoftStyle& LIBRARY
  2825.     'SetDrMd
  2826.  
  2827.     LIBRARY "graphics.library"
  2828.  
  2829.     init:    normal = 0
  2830.         underline = 2^0
  2831.         bold = 2^1
  2832.         italic = 2^2
  2833.         CLS
  2834.  
  2835.     main: '* JAM1 for legible slanted text.
  2836.         CALL SetDrMd(WINDOW(8),0)
  2837.         LOCATE 4,1
  2838.         SetStyle underline+bold
  2839.         PRINT TAB(8);"ALGORITHM GENERATED TEXT STYLES"
  2840.         PRINT
  2841.         SetStyle normal
  2842.         PRINT "The Amiga can do a lot the the existing fonts."
  2843.         PRINT "without a ";
  2844.         SetStyle underline
  2845.         PRINT "Definition Change";
  2846.         SetStyle normal
  2847.         PRINT "You can use these styles:"
  2848.         PRINT
  2849.         SetStyle bold
  2850.         PRINT "BOLD Print"
  2851.         SetStyle italic
  2852.         PRINT "ITALIC Print"
  2853.         SetStyle underline
  2854.         PRINT "UNDERLINED text"
  2855.         SetStyle underline+italic
  2856.         PRINT "and MIXED."
  2857.         PRINT
  2858.         SetStyle normal
  2859.         PRINT "These tricks let you display text professionally."
  2860.  
  2861.                 PAGE 146
  2862.  
  2863. ----------------------------------------------------------------------------
  2864.  
  2865.         CALL SetDrMd(WINDOW(8),1)
  2866.  
  2867.         LIBRARY CLOSE
  2868.         END
  2869.  
  2870.     SUB SetStlye(mode) STATIC
  2871.         '0   = normal
  2872.         '2^0 = underline
  2873.         '2^1 = bold
  2874.         '2^2 = italic
  2875.         mode%=CINT(mode)
  2876.  
  2877.         '* Check font and if possible set new style.
  2878.         enable%   = AskSoftStyle&(WINDOW(8))
  2879.         newstyle% = SetSoftStyle&(WINDOW(8),mode%,enable%)
  2880.     END SUB
  2881.  
  2882. You probably noticed that the italic print in the first example was 
  2883. somewhat deformed but in the above example the italics looked much better.
  2884. The reason for this is that italics only work correctly in JAM1 mode. When
  2885. characters are slanted, the right side of each character extends slightly 
  2886. into the next character's position. If the normal JAM2 mode is active,
  2887. this overlap is covered by the background colour making the character look
  2888. chopped off.
  2889.  
  2890.                 PAGE 147
  2891.  
  2892. ----------------------------------------------------------------------------
  2893.  
  2894. 3.8 THE RASTPORT AND THE GRAPHIC SYSTEM.
  2895.  
  2896. We'll now look at the RastPort an relation to the graphic system if the 
  2897. Amiga. Youll see that the RastPort becomes a component of windows and 
  2898. screens.
  2899.  
  2900.         __________________________________
  2901.            |                                  |
  2902.             |     R  A  S  T  P  O  R  T       |
  2903.       Bitmap --|---                               |
  2904.            |                        |         |
  2905.            |________________________|_________|
  2906.                     |
  2907.                     Layer
  2908.  
  2909. With this we can represent the entire system much better. Below we have 
  2910. added a RastPort to the figure from Section 3.5:
  2911.  
  2912.                __________________________
  2913.               |                          |
  2914.        _______|____ S  C  R  E  E  N   __|_________________  
  2915.       |       |                             |                 |
  2916.       |       |                         __|___________      |
  2917.    Viewport.  |___|_____|________________|           |     |
  2918.           |     |                  ___|_____|_______|__ 
  2919.           |     |     _____               |           |  |
  2920.           |     |____|     |              |    W I N D O W    |
  2921.                   |      ____| R P |              |                ---|---
  2922.           |     |    |_____|              |                   |
  2923.           |     |                         |   |            |  |
  2924.                               |___|____________|__|
  2925.                               |            |
  2926.                            ___|___
  2927.                               |       |
  2928.                      BitMap<--|  R P  |
  2929.                               |_______|
  2930.                                |
  2931.                                |
  2932.  
  2933. We still need information about ViewPort, Bit-Map and Layers. However, the 
  2934. picture we are building of the Amiga operating system is becoming much 
  2935. clearer. Our next subject is the bit-map data structure.
  2936.  
  2937.                 PAGE 148
  2938.  
  2939. ----------------------------------------------------------------------------
  2940.  
  2941. 3.9 THE BIT-MAP STRUCTURE.
  2942.  
  2943. Through this structure we gain access to the RAM banks where the screen 
  2944. contents are stored. This data structure is 40 bytes long:
  2945.  
  2946. Offset    Type    Description.
  2947. ------- ------- -----------------------------------
  2948. +000    Word    Bytes per display line.
  2949. +002    Word    Number of display lines.
  2950. +004    Byte    System flag (unused)
  2951. +005    Byte    Number of bit-planes (depth)
  2952. +006     Word    Unused.
  2953. +008    Long    Pointer to 1st bitplane.
  2954. +012    Long    Pointer to 2nd bitplane.
  2955. +016    Long    Pointer to 3rd bitplane.
  2956. +020    Long    Pointer to 4th bitplane.
  2957. +024    Long    Pointer to 5th bitplane.
  2958. +028    Long    Pointer to 6th bitplane.
  2959. +032    Long    Pointer to 7th bitplane.
  2960. +036    Long    Pointer to 8th bitplane.
  2961.  
  2962. You obtain the starting address of the data structure like this:
  2963.  
  2964.     bitmap& = PEEKL(WINDOW(8)+4)
  2965.  
  2966. The first two fields contain the screen measurements stored by the 
  2967. bit-planes:
  2968.  
  2969.     bitmap& = PEEKL(WINDOW(8)+4)
  2970.     x%=PEEKW(bitmap&)*8
  2971.     y%=PEEKW(bitmap&+2)
  2972.     PRINT "Extent : horiz. ";x%;
  2973.     PRINT "vert. ";y%
  2974.  
  2975. The fourt field contains the number of used bit-planes. Presently you can
  2976. only have up to six active bit-planes. The pointers for planes seven and
  2977. eight are for future expansion compatibility of the Amiga.
  2978.  
  2979.                 PAGE 149
  2980.  
  2981. ----------------------------------------------------------------------------
  2982.  
  2983.                        CHAPTER 4 - THE VIEWPORT
  2984.  
  2985.  
  2986. We have now covered almost all of the graphic hardware. The ViewPort which
  2987. consists of a data block of 40 bytes, represents the most elementary 
  2988. display of the Amiga.
  2989.  
  2990. Data Structure - Viewport/graphics/40 bytes.
  2991.  
  2992. Offset  Type    Description.
  2993. ------- ------- ------------------------------------------
  2994. +000    Long    Pointer to next viewport.
  2995. +004    Long    Pointer to ColorMap.
  2996. +008    Long    DspIns: Copper list from Make View.
  2997. +012    Long    SprIns: Copper list for sprites.
  2998. +016    Long    ClrIns: Copper list for sprites.
  2999. +020    Long    UCopIns: User copper list.
  3000. +024    Word    Width of display
  3001. +026    Word    Height of display.
  3002. +028    Word    X Offset from (0,0) of bit-plane.
  3003. +030    Word    Y Offset from (0,0) of bit-plane.
  3004. +032    Word    ViewPort mode:
  3005.                     Bit 1  :  1 = GENLOCK VIDEO.
  3006.                     Bit 2  :  1 = INTERLACE.
  3007.                     Bit 6  :  1 = PFBA
  3008.                     Bit 7  :  1 = EXTRA HALFBRITE
  3009.                     Bit 8  :  1 = GENLOCK VIDEO.
  3010.                     Bit 10 :  1 = DUALPF
  3011.                     Bit 11 :  1 = HAM
  3012.                     Bit 13 :  1 = VP_HIDE.
  3013.                     Bit 14 :  1 = SPRITES.
  3014.                     Bit 15 :  1 = HIRES.
  3015. +034    Word    reserved.
  3016. +036    Long    Pointer to RasInfo structure.
  3017.  
  3018. Before we cover the offset description, we must explain the importance of
  3019. a ViewPort.
  3020.  
  3021. A ViewPort is a data structure in RAM which represents a part of what you 
  3022. see on the screen. If you take a close look at the screen structure in
  3023. section 3.4 you will see that the ViewPort is part of this structure. The
  3024. reason for this is that an Intuition screen is really a ViewPort with 
  3025. accessories. So the heart of every screen is a ViewPort.
  3026.  
  3027.                                 PAGE 151
  3028.  
  3029. ---------------------------------------------------------------------------------
  3030.  
  3031. A display consists of one or more ViewPorts. The following diagram 
  3032. illustrates this :
  3033.  
  3034.  
  3035.     ********************************************************************
  3036.     *                                                                  *
  3037.     *    --------------------------                                    *
  3038.     *   |                          |                                   *
  3039.     *   |                          |                                   *
  3040.     *   |       VIEWPORT 1         |                                   *
  3041.     *   |                          |                                   *
  3042.     *   |__________________________|                                   *
  3043.     *                                                                  *
  3044.     *      ______________________________________________              *
  3045.     *     |                                              |             *
  3046.     *     |                                              |             *
  3047.     *     |                                              |             *
  3048.     *     |               VIEWPORT 2                     |             *
  3049.     *     |                                              |             *
  3050.     *     |                                              |             *
  3051.     *     |______________________________________________|             *
  3052.     *                                                                  *
  3053.     *                                    ___________________________   *
  3054.     *                                   |                           |  *
  3055.     *                                   |         VIEWPORT 3        |  *
  3056.     *                                   |                           |  *
  3057.     *                                   |___________________________|  *
  3058.     *                                                                  *
  3059.     ********************************************************************
  3060.  
  3061. ViewPorts have the following restrictions : 1.) it is not possible to place
  3062. viewports next to each other. 2.) A ViewPort cannot overlap another 
  3063. ViewPort. 3.) there must be at least one pixel row betwen them.
  3064.  
  3065. Each ViewPort can have it's own graphic attributes like colour and 
  3066. bit-plane. Also, the ViewPort is further divided among several areas called
  3067. windows. However, windows do not have the same limitations as ViewPorts and
  3068. they can overlap each other.
  3069.  
  3070. Now we will present a detailed description of the data structure.
  3071.  
  3072.                                 PAGE 152
  3073.  
  3074. -----------------------------------------------------------------------------
  3075.  
  3076.  
  3077. 4.1 THE VIEWPORT DATA STRUCTURE.
  3078.  
  3079. OFFSET 0 : NEXT VIEWPORT.
  3080.  
  3081. A display can consist of one or more ViewPorts connected in a chain. This
  3082. field points to the next ViewPort of a display. If there are no further 
  3083. ViewPorts, this field equals zero.
  3084.  
  3085. OFFSET 4: COLOUR MAP.
  3086.  
  3087. Every ViewPort can define it's own colour. This offset points to a data
  3088. structure called "colormap" which stores the RGB value if this colour.
  3089. Depending on how many bit-planes are available, a ViewPort can use up to 32
  3090. individual colours (without using special modes).
  3091.  
  3092. OFFSET 8, 12, 16 AND 20: COPPER LIST.
  3093.  
  3094. The Copper, which is one of three Amiga graphic coprocessors, controls the
  3095. entire display, manipulates registers, moves sprites and programs the 
  3096. blitter (the copy processor). A special programming language designed 
  3097. exclusively for the Copper consists of three commands. This field of the 
  3098. ViewPort structure contains the copper command list which the Copper uses
  3099. to build a display. The first list determines how to link the other three
  3100. lists and use them to display the ViewPort.
  3101.  
  3102. OFFSET 24 AND 26: WIDTH AND HEIGHT.
  3103.  
  3104. These two offsets contain the width and height of the display section 
  3105. controlled by this ViewPort.
  3106.  
  3107. OFFSET 28 AND 30: BITMAP OFFSET.
  3108.  
  3109. At this offset we find the coordinates of the upper left hand corner of the
  3110. ViewPort relative to the complete display. These values are used to position
  3111. the ViewPort. DyOffset can vary between -16 and +200 (interlace -32 to +400)
  3112. DxOffset can vary between -16 and +352 (in hires -32 to +704).
  3113.  
  3114. OFFSET 32: THE VIEWPORT MODES.
  3115.  
  3116. The amiga has many different graphic modes. The most well known are hi-res
  3117. (640 pixels horizontal) and interlace (400 pixels vertically). This 
  3118. field contains a value for the current mode. 
  3119.  
  3120.  
  3121.                                 PAGE 153
  3122.  
  3123. -----------------------------------------------------------------------------
  3124.  
  3125. OFFSET 36: THE RASINFO BLOCK.
  3126.  
  3127. Every ViewPort has at least one RasInfo data structure connected to it. We 
  3128. will discuss this further on. 
  3129.  
  3130.                                  PAGE 154
  3131.  
  3132. -----------------------------------------------------------------------------
  3133.  
  3134. 4.2 THE GRAPHIC MODES OF THE AMIGA.
  3135.  
  3136. The amiga has the following nine special graphic modes :
  3137.  
  3138.         Genlock Video.
  3139.         Interlace.
  3140.         PFBA.
  3141.         Extra halfbrite.
  3142.         DUALPF
  3143.         HAM
  3144.         VP-Hide
  3145.         SPrites
  3146.         Hi-res
  3147.  
  3148. You should already be familiar with the hi-res and interlace modes supported
  3149. by AmigaBASIC. The AmigaBASIC SCREEN statement can specify screens from 
  3150. lo-res (normal 320 pixels wide), hi-res (640 pixels wide) to interlace 
  3151. (400 instead of 200 pixels high).
  3152.  
  3153. If the ViewPort will contain sprites or Vsprites, you must set the sprite 
  3154. flag (this is normally true).
  3155.  
  3156. VP-Hide is set whenver this ViewPort is covered by other ViewPorts (for
  3157. example, a screen covers another screen). The other viewport is not 
  3158. displayed.
  3159.  
  3160. Genlock Video means that instead of the background colour, an external
  3161. video signal, like a video recorder or camera, provides the background.
  3162. You need a genlock interface to use this mode.
  3163.  
  3164. DUALPF stands for "dual playfield". This mode allows you to display two
  3165. different planes in one ViewPort. The background of the top plane becomes
  3166. transparent to show the plane underneath.
  3167.  
  3168. PFBA works with the dual playfield mode. It determines the video priority 
  3169. of the two planes.
  3170.  
  3171. HAM stands for Hold and Modify. This mode allows you to display all 4096
  3172. colours of the Amiga on the screen at the same time. However, this display
  3173. mode is very difficult to program. More on this subject shortly.
  3174.  
  3175. Extra halfbrite is a new graphic mode that allows you to display up to 64
  3176. colors at the same time instead of the normal 32.
  3177.  
  3178.                                 PAGE 155
  3179.  
  3180. -----------------------------------------------------------------------------
  3181.  
  3182. 4.2.1 THE HALFBRITE MODE.
  3183.  
  3184. Extra halfbrite is one of the special graphic modes not supported by the 
  3185. BASIC SCREEN statement. It is therefore impossible to create a screen in 
  3186. this mode using SCREEN.
  3187.  
  3188. It is possible to convert an existing screen to a halfbrite screen. Before 
  3189. we show you how to do this we are going to explain the halfbrite technique.
  3190.  
  3191. Normally the Amiga can only display up to 32 colors at one time. This is 
  3192. because of two factors: 1.) The number of available colours is determined
  3193. by the number of bit-planes (5, 2^5=32)and 2). The Amiga has 32 colour 
  3194. registers to store colour values that were defined using the AmigaBASIC 
  3195. PALETTE statement.
  3196.  
  3197. When the halfbrite mode is active, you have six bit-planes available and the
  3198. number of available colours increases accordingly from 2^5=32 to 2^6=64.
  3199. However, since there are only 32 colour registers, there isnt space for the
  3200. other 32 colours. To  solve this problem we use the 32 registers twice. We
  3201. obtain colours 0 to 31 directly from registers 0 to 31. Colours 32 to 63 
  3202. are also obtained from registers 0 to 31 but the RGB values in the registers
  3203. are shifted one bit to the right.
  3204.  
  3205. However, this causes three effects: 1.) The extra 32 halfbrite colours 
  3206. cannot be freely defined because they rely on the values of the first 32
  3207. colours. 2.) the extra colours are copies of the existing colours but are
  3208. darker (therefore the name halfbrite), and 3.) if the first 32 colours are
  3209. very dark there will be little visible difference between them and the 
  3210. second 32 colors.
  3211.  
  3212. Although these limits may sound troublesome, the halfbrite mode is still 
  3213. reqarding because you can have an extra 32 slightly darker variations of 
  3214. your first 32 colours to work with.
  3215.  
  3216. Since we cannot normally active the halfbrite mode with BASIC, we are going
  3217. to create a screen with a depth of five bit-planes. From the information
  3218. in the previous chapters, we know the Amiga graphics system fairly well by
  3219. now. Therefore, it should not be difficult to set up a sixth bit-plane in
  3220. the bit-map structure of the screen. Finally, set the halfbrite flags in 
  3221. the ViewPort. (There is just one small problem that we will cover shortly).
  3222.  
  3223. To mke our screen a reality, we have to access two system libraries :
  3224. We need the following functions :
  3225.  
  3226.         RemakeDisplay()
  3227.         AllocMem()
  3228.         FreeMem()
  3229.  
  3230.                                 PAGE 156
  3231.  
  3232. -----------------------------------------------------------------------------
  3233.  
  3234.  
  3235. Our program, the halfbrite activator, follows. In addition to the 
  3236. demonstration program there are two SUB programs, HalfBriteOn and 
  3237. HalfBriteOff. Neither SUB requires any arguments.
  3238.  
  3239.         '#####################################
  3240.         '#
  3241.         '# Section : 4.2.1
  3242.         '# Program : Halfbrite Activator.
  3243.         '# Date    : 01/17/87
  3244.         '# Author  : tob
  3245.         '# Version : 1.1
  3246.         '#
  3247.         '#######################################
  3248.         '
  3249.         ' Activates the Amiga special graphic mode "halfbrite"
  3250.         ' Not normally available in BASIC. With 6 bit-planes
  3251.         ' there are a total of 64 different colours available.
  3252.         ' We will explain the functions and the most effective
  3253.         ' programming methods for this mode in this book. NOTE :
  3254.         ' This mode only functions in LoRes mode.
  3255.  
  3256.         PRINT "Searching for .bmap file ..... "
  3257.  
  3258.         'EXEC-Library
  3259.         DECLARE FUNCTION AllocMem& LIBRARY
  3260.         'FreeMem
  3261.         'INTUITION-LIBRARY
  3262.         'RemakeDisplay()
  3263.         
  3264.         LIBRARY "intuition.library"
  3265.         LIBRARY "exec.library"
  3266.  
  3267.         main:
  3268.             loRes            = 1
  3269.             screen.nr%       = 1
  3270.             screen.x%        = 320
  3271.             screen.y%        = 200
  3272.             screen.depth%    = 5 '5 planes required'
  3273.             screen.resolution% = loRes
  3274.             SCREEN screen.nr%,screen.x%,screen.y%,screen.depth%,
  3275. screen.resolution%
  3276.  
  3277.             'Open a window in the new screen.
  3278.             windo.nr%          = 1
  3279.             windo.name$        = "Halfbrite!"
  3280.             WINDOW windo.nr%,windo.name$,,,screen.nr%
  3281.  
  3282.  
  3283.                                 PAGE 157
  3284.  
  3285. -----------------------------------------------------------------------------
  3286.  
  3287.         demo: 'Activate Halfbrite
  3288.             HalfBriteOn
  3289.  
  3290.             PRINT TAB(10);"The HalfBrite Mode!"
  3291.              
  3292.             'The original colours.
  3293.             LOCATE 3,2:COLOR 1,0
  3294.  
  3295.             PRINT "A ";
  3296.             FOR loop%=0 TO 31
  3297.                 COLOR 0,loop%
  3298.                 PRINT " ";
  3299.             NEXT loop%
  3300.  
  3301.             '*  ... and the halfbrite colours.
  3302.             PRINT "B ";
  3303.             FOR loop% = 32 TO 63
  3304.                 COLOR 0,loop%
  3305.                 PRINT " ";
  3306.             NEXT loop%
  3307.  
  3308.             LINE (22,15)-(280,32),1,b
  3309.             LOCATE 7,2:COLOR 1,0
  3310.             PRINT "A: The 32 original colours, stored"
  3311.             PRINT "   in the hardware colour registers."
  3312.  
  3313.             LOCATE 10,2
  3314.             PRINT "B: The additional 32 HalfBrite "
  3315.             PRINT "   colours, corresponding to the "
  3316.             PRINT "   original colours at half intensity"
  3317.  
  3318.             LOCATE 14,2
  3319.             PRINT " The blinking sample shows when the"
  3320.             PRINT " Colour register of the original colour"
  3321.             PRINT " is changed, the HalfBrite colour is"
  3322.             PRINT " changed accordingly."
  3323.  
  3324.             LOCATE 19,4
  3325.             PRINT "Press the left mouse button"
  3326.  
  3327.             WHILE check% = 0
  3328.                 check% = MOUSE(0)
  3329.                 PALETTE 30,.7,.2,.9
  3330.                 FOR t = 1 TO 500 : NEXT t
  3331.                 PALETTE 30,.3,.8,.1
  3332.                 FOR t = 1 TO 500 : NEXT t
  3333.             WEND
  3334.  
  3335.             FOR loop% = 0 TO 31
  3336.                 COLOR loop%,loop%+32
  3337.                 LOCATE 20,1
  3338.                 PRINT "TEST COLOUR ";loop%
  3339.                 PRINT "Text Colour            - Original colour"
  3340.                 PRINT "Background Colour      - Halfbrite colour"
  3341.                 FOR t = 1 TO 500: NEXT t
  3342.             NEXT loop%
  3343.             CLS
  3344.             COLOR 1,0
  3345.  
  3346.  
  3347.                                 PAGE 158
  3348.  
  3349. ---------------------------------------------------------------------------
  3350.  
  3351.         endprog:   ' Halfbrite off and close screen. '
  3352.             HalfBriteOff
  3353.             WINDOW windo.nr%,windo.name$,,,-1
  3354.             SCREEN CLOSE screen.nr%
  3355.             PRINT "End of DEMO !"
  3356.             LIBRARY CLOSE
  3357.             END
  3358.  
  3359.         SUB HalfBriteOn STATIC
  3360.             SHARED screen.mode%
  3361.             SHARED screen.viewport&
  3362.  
  3363.             ' Define variables.
  3364.             MEM.CHIP    = 2^1
  3365.             MEM.CLEAR   = 2^16
  3366.             memory.option& = MEM.CHIP + MEM.CLEAR
  3367.             window.base&   = WINDOW(7)
  3368.             screen.base&   = PEEKL(window.base&+46)
  3369.             screen.bitmap& = screen.base&+184
  3370.             screen.viewport&=screen.base& + 44
  3371.             screen.rastport&=screen.base& + 84
  3372.             screen.width%   = PEEKW(screen.bitmap&)
  3373.             screen.height%  = PEEKW(screen.bitmap&+2)
  3374.             screen.size&    = screen.width%*screen.height%
  3375.             screen.depth%   = PEEK(screen.bitmap&+5)
  3376.             screen.mode%    = PEEKW(screen.viewport&+32)
  3377.  
  3378.             '* SCREEN already has 6 bitplanes ????
  3379.             IF screen.depth%>5  THEN screen.depth%=2^8
  3380.  
  3381.             '* add missing Bitplanes.
  3382.             FOR loop1% = screen.depth%+1 TO 6
  3383.                 plane&(loop1%)   = AllocMem&(screen.size&,memory.options&)
  3384.                 IF plane&(loop1%) = 0 THEN
  3385.                     FOR loop2% = screen.depth%+1 TO loop1%-1
  3386.                         CALL FreeMem(plane&(loop2%),screen.size&)
  3387.                     NEXT loop2%
  3388.                     ERROR 7
  3389.                 END IF
  3390.                 POKEL screen.bitmap&+4+4*loop1%,plane&(loop1%)
  3391.             NEXT loop1%
  3392.             POKE screen.bitmap&+5,6
  3393.  
  3394.             'Halfbrite on
  3395.             POKEW screen.viewport&+32,(screen.mode% OR 2^7)
  3396.             CALL RemakeDisplay
  3397.         END SUB
  3398.  
  3399.         SUB HalfBriteOff STATIC
  3400.             SHARED screen.mode%
  3401.             SHARED screen.viewport&
  3402.  
  3403.             'Reset Halfbrite Flag
  3404.             POKEW screen.viewport&+32,screen.mode%
  3405.             CALL RemakeDisplay
  3406.         END SUB
  3407.  
  3408.                                 PAGE 159
  3409.  
  3410. -----------------------------------------------------------------------------
  3411.  
  3412. Working with the halfbrite program :
  3413.  
  3414. After you call the SUB "HalfBriteOn" you will have 64 different colours
  3415. available. You can freely define the first 32 colours using the BASIC 
  3416. PALETTE statement:
  3417.  
  3418.         PALETTE register, reg, green, blue
  3419.  
  3420.         register : 0,31
  3421.         red,green,blue : 0.0 - 1.0
  3422.  
  3423. Colours 32 to 63 are defined at the same time except they are half as 
  3424. bright.
  3425.  
  3426. With the COLOR statement you can select any colour from 0 TO 63, draw, 
  3427. print text and fill. But you should remember that for AmigaBASIC, the 
  3428. screen still only has five bit-planes. When BASIC scrolls the screen (when
  3429. you write text in the last row) only five planes will scroll; the sixth
  3430. plane stays in place. To avoid this problem do not print to the last screen
  3431. line.
  3432.  
  3433. When you no longer need the HalfBrite mode you can deactivate it by using
  3434. the SUB "HalfBriteOff".
  3435.  
  3436. At the beginning of this section we mentioned a problem involving changes 
  3437. to the HalfBrite flag in the ViewPort. Setting this flag does not do 
  3438. anything. It doesn't matter what type of manipulation you perform in the 
  3439. ViewPort, nothing is changed in the display. 
  3440.  
  3441. This happens because the display is only changed by the hardware registers.
  3442. Since ViewPort is a data block in RAM and not a hardware register, the 
  3443. display isn't changed. In order to affect the display. the information
  3444. in ViewPort about how the display is formed must first be sent to the 
  3445. Copper. This is because the Copper controls and programs the hardware.
  3446.  
  3447. We make ViewPort changes effective when we call the Intuition function
  3448. "RemakeDisplay". This function creates a new Copper list and reflects the 
  3449. change in the ViewPort structure. Finally, this list is sent to the 
  3450. Copper.
  3451.  
  3452.                                 PAGE 160
  3453.  
  3454. -----------------------------------------------------------------------------
  3455.  
  3456. 4.2.2 THE HOLD AND MODIFY MODE : 4096 COLOURS.
  3457.  
  3458. The Hold and Modify mode (abbr. HAM) is also not supported by AmigaBASIC.
  3459. You cannot access it by using the SCREEN statement.
  3460.  
  3461. We can activate this mode for a screen that already exists. Before we do 
  3462. this, let's take a look at the principles for using this mode.
  3463.  
  3464. When the HAM mode is active, you can display up to 4096 colours at the 
  3465. same time. If we follow the normal rules for displaying 4096 colours, we 
  3466. would require 12 bit-planes. This would require a large amount of memory 
  3467. (1 bit-plane = 64000 bytes in lo-res, 12 bit-planes = 768000 bytes!). Also
  3468. the Amiga's DMA (Direct Memory Access) is not fast enough to retrieve and 
  3469. build a new screen every 1/60th of a second from 12 different RAM areas. 
  3470. Obviously, we need a special procedure.
  3471.  
  3472. Actually, HAM works with only 6 bit-planes just as the halfbrite mode. The 
  3473. first 16 colours are the exact colours that were defined for the first 16
  3474. colour registers. All other colours are determined by the HAM principle.
  3475. They use the colour of the pixel to the left and modify the RGB value.
  3476.  
  3477. Before we undertake the complex arrangement of a HAM graphic, we need to 
  3478. activate the mode. This is very similar to the halfbrite mode. We create
  3479. a sixth bit-plane, add it to the bit-map and then set the HAM flag in the
  3480. ViewPort. A call to RemakeDisplay switches the display to HAM. Again, there
  3481. are two SUB programs, HAMon and HAMoff.
  3482.  
  3483.         '#####################################
  3484.         '#
  3485.         '# Section : 4.2.2
  3486.         '# Program : HAM activator.
  3487.         '# Date    : 02/16/87
  3488.         '# Author  : tob
  3489.         '# Version : 1.4
  3490.         '#
  3491.         '#######################################
  3492.         '
  3493.         ' Activates the Amiga special graphic mode "HAM" (Hold 
  3494.         ' And Modify) not normally availble to BASIC. Provides 
  3495.         ' up to 4096 colours at the same time (with 6
  3496.         'bit-planes. NOTE : only functions in lores mode.
  3497.  
  3498.         PRINT "Searching for .bmap file ..... "
  3499.  
  3500.                                 PAGE 161
  3501.  
  3502. -----------------------------------------------------------------------------
  3503.  
  3504.         'EXEC-Library
  3505.         DECLARE FUNCTION AllocMem& LIBRARY
  3506.         'FreeMem
  3507.         'INTUITION-LIBRARY
  3508.         'RemakeDisplay()
  3509.         
  3510.         LIBRARY "intuition.library"
  3511.         LIBRARY "exec.library"
  3512.  
  3513.         main:
  3514.             loRes            = 1
  3515.             screen.nr%       = 1
  3516.             screen.x%        = 320
  3517.             screen.y%        = 200
  3518.             screen.depth%    = 5 '5 planes required'
  3519.             screen.resolution% = loRes
  3520.             SCREEN screen.nr%,screen.x%,screen.y%,screen.depth%,
  3521. screen.resolution%
  3522.  
  3523.             'Open a window in the new screen.
  3524.             windo.nr%          = 1
  3525.             windo.name$        = "HAM! 4096 colours available.!"
  3526.             WINDOW windo.nr%,windo.name$,,,screen.nr%
  3527.  
  3528.         demo: 'Activate HAM
  3529.             HAMon
  3530.  
  3531.             PRINT TAB(7);"256 of 4096 colours"
  3532.              
  3533.             s = 10                ' box size
  3534.             x = 40                ' Position of upper
  3535.             y = 20                ' left corner of demo.
  3536.             PALETTE 3,0,0,0       ' FRAME COLOUR.
  3537.             PALETTE 4,.5,0,.5     ' DARK PURPLE.
  3538.             PALETTE 5,1,0,1       ' LIGHT PURPLE.
  3539.             PALETTE 6,1,0,0       ' LIGHT RED.
  3540.             PALETTE 7,0,0,1       ' LIGHT BLUE.
  3541.  
  3542.             'SET ORIENTATION MARKS.
  3543.             LINE (5,y)-(5+8,y+8),4,bf
  3544.             LINE (240,y)-(240+8,y+8),7,bf
  3545.             LINE (5,166)-(5+8,166+8),6,bf
  3546.             LINE (240,166)-(240+8,166+8),5,bf
  3547.  
  3548.             ' DRAW FRAME.
  3549.             LINE (x-1,y-1)-(x+17*s+1,y+16*s+1),3,b
  3550.  
  3551.             ' Draw first 256 HAM colours.
  3552.             FOR loop% = 0 TO 15
  3553.                 LINE (x,loop%*s+y)-(s+x,loop%*s+s+y),32+loop%,bf
  3554.                 FOR loop2% = 0 TO 15
  3555.                     LINE (s+loop2%*s+x,loop%*s+y)-(2*s+loop2%*s+x,
  3556. loop%*s+s+y),loop2%+16,bf
  3557.                 NEXT loop2%
  3558.             NEXT loop%
  3559.  
  3560.                                 PAGE 162
  3561.  
  3562. -----------------------------------------------------------------------------
  3563.  
  3564.         '* Raise Green Level.
  3565.         FOR loop2% = 0 TO 15
  3566.             PALETTE 3,0,loop2%*(1/15),0
  3567.             LOCATE 10,28
  3568.             PRINT "Green Level: "
  3569.             PRINT TAB(31) loop2%
  3570.             FOR t = 1 TO 3000: NEXT t
  3571.         NEXT loop2%
  3572.  
  3573.         LOCATE 2,7
  3574.         PRINT "Please Press a Key ! "
  3575.         WHILE INKEY$ = "": WEND
  3576.  
  3577.         endprog:   ' HAM off and close screen. '
  3578.             HAMOff
  3579.             WINDOW windo.nr%,windo.name$,,,-1
  3580.             SCREEN CLOSE screen.nr%
  3581.             PRINT "End of DEMO !"
  3582.             LIBRARY CLOSE
  3583.             END
  3584.  
  3585.         SUB HAMOn STATIC
  3586.             SHARED screen.mode%
  3587.             SHARED screen.viewport&
  3588.  
  3589.             ' Define variables.
  3590.             MEM.CHIP    = 2^1
  3591.             MEM.CLEAR   = 2^16
  3592.             memory.option& = MEM.CHIP + MEM.CLEAR
  3593.             window.base&   = WINDOW(7)
  3594.             screen.base&   = PEEKL(window.base&+46)
  3595.             screen.bitmap& = screen.base&+184
  3596.             screen.viewport&=screen.base& + 44
  3597.             screen.rastport&=screen.base& + 84
  3598.             screen.width%   = PEEKW(screen.bitmap&)
  3599.             screen.height%  = PEEKW(screen.bitmap&+2)
  3600.             screen.size&    = screen.width%*screen.height%
  3601.             screen.depth%   = PEEK(screen.bitmap&+5)
  3602.             screen.mode%    = PEEKW(screen.viewport&+32)
  3603.  
  3604.             '* SCREEN already has 6 bitplanes ????
  3605.             IF screen.depth%>5  THEN screen.depth%=2^8
  3606.  
  3607.             '* add missing Bitplanes.
  3608.             FOR loop1% = screen.depth%+1 TO 6
  3609.                 plane&(loop1%)   = AllocMem&(screen.size&,memory.options&)
  3610.                 IF plane&(loop1%) = 0 THEN
  3611.                     FOR loop2% = screen.depth%+1 TO loop1%-1
  3612.                         CALL FreeMem(plane&(loop2%),screen.size&)
  3613.                     NEXT loop2%
  3614.                     ERROR 7
  3615.                 END IF
  3616.                 POKEL screen.bitmap&+4+4*loop1%,plane&(loop1%)
  3617.  
  3618.                                 page 163
  3619.  
  3620. -----------------------------------------------------------------------------
  3621.  
  3622.             NEXT loop1%
  3623.             POKE screen.bitmap&+5,6
  3624.  
  3625.             'HAM on
  3626.             POKEW screen.viewport&+32,(screen.mode% OR 2^11)
  3627.             CALL RemakeDisplay
  3628.         END SUB
  3629.  
  3630.         SUB HAMOff STATIC
  3631.             SHARED screen.mode%
  3632.             SHARED screen.viewport&
  3633.  
  3634.             'Reset HAM Flag
  3635.             POKEW screen.viewport&+32,screen.mode%
  3636.             CALL RemakeDisplay
  3637.         END SUB
  3638.  
  3639.  
  3640. After you start this program you will see a field of 256 colours that were
  3641. created by using only red and blue. In the top left hand corner is a dark
  3642. purple colour and in the lower right hand corner, a light purple colour.
  3643. Light red is in the lower left hand corner and light blue is in the upper
  3644. right hand corner.
  3645.  
  3646. Now we blend a green slowly and evenly with other colours to display all 
  3647. 4096.
  3648.  
  3649. This mass of colours looks very impressive but programming them is not easy.
  3650. But, as you will see, it is not too complicated.
  3651.  
  3652. First, lets define the difference between real colours and HAM colours. Real
  3653. colors, the colours 0-15, actually display the values in colour registers
  3654. 0-15. These colours are permanent and can only be changed with the 
  3655. PALETTE statement. The HAM colours, 16-63 are different because they are 
  3656. always affected by their neighbouring colour to the left. A HAM colour takes
  3657. the colour of the pixel to the left and modifies the RGB components. Which
  3658. of the three components that is changed depends on the HAM colour itself.
  3659.  
  3660.         Color 0           - 15         Real Colour.
  3661.         Color 16+0        - 16+15      HAM type 1.
  3662.         Color 32+0        - 32+15      HAM type 2.
  3663.         Color 48+0        - 48+15      HAM type 3.
  3664.  
  3665. HAM colour type 1 takes the neighbouring colour and changes the blue 
  3666. component. The blue component of the HAM colour corresponds to a value 
  3667. higher than 16. The HAM colour 16+12=28 uses the neighbouring colour
  3668. and makes a value of 12 for blue.
  3669.  
  3670.                                 PAGE 164
  3671.  
  3672. -----------------------------------------------------------------------------
  3673.  
  3674. HAM colour type 2 takes the nieghbouring colour and modifies the red 
  3675. component. The HAM colour 32+8 = 40 takes the nighbouring colour and makes
  3676. a value of 8 in the red component.
  3677.  
  3678. HAM colour type 3 performs exactly the same function for colours 48 and up,
  3679. changing the green component.
  3680.  
  3681. In our example program we created a black frame making red, green and 
  3682. blue = 0. Directly to the right of the frame we drew with a HAM colour
  3683. of type 2. This colour checks the pixel colour to the left, the black 
  3684. frame and uses the same color. Reg,Green and Blue are still zero. The Blue
  3685. field is set by the HAM colour itself. This blue value increases in a loop
  3686. that changes every screen row.
  3687.  
  3688. Directly to the right of this HAM colour we drew 16 HAM colours of type 1.
  3689. These add in a red value of one.
  3690.  
  3691. This creates the colourpattern. The red intensity increases to the right
  3692. and the blue intensity increases downward.
  3693.  
  3694. Now we change the colour of the frme by making the previously black frame 
  3695. greener with the PALETTE command. The green value of the frame passes 
  3696. immediately to the HAM colours. The entire colour graphic effect results
  3697. from an increasing green intensity.
  3698.  
  3699.                                 PAGE 165 
  3700.  
  3701. -----------------------------------------------------------------------------
  3702.  
  3703. 4.3 THE VIEWPORT IN THE SYSTEM.
  3704.  
  3705. We now have a clearer picture of the amiga system. You shouldbe familiar 
  3706. with two components; the bit-map and the ViewPort. Both are easily 
  3707. illustrated.                
  3708.                             
  3709.                     __________________________
  3710.                        |                          |
  3711.                            |          BitMap          |   
  3712.                        |                          |
  3713.                                        |_____________|_|_|_|_|_|__|
  3714.          ______________           |   |      | | | | | | bitplanes
  3715.         |              | _________|   |                  (max 8)
  3716.         | bitplane 1   |              |         
  3717.                 |______________|              |   
  3718.                                               |  
  3719.               ______________              |  
  3720.         |              | _____________|  
  3721.                 | bitplane 2   |
  3722.                 |______________|                        next viewport
  3723.                 
  3724.                     _____________________|____
  3725.                        |                     |    |
  3726.                        |     ViewPort             |
  3727.                    ----|              |-----
  3728.                   Color map    |__________________________|Rasinfo
  3729.  
  3730.  
  3731.  
  3732. Now the system connection with these components.
  3733.  
  3734.  
  3735.         __|_____________
  3736.                |                | 
  3737.                |  Screen        |<----------------
  3738.         ___|                |                 |  
  3739.            |   |                |------           |
  3740.            |   |________________|      |          |
  3741.            |       |    |   ____       |          |
  3742.            |       |    |__|    |   ___|__________|__|__
  3743.            |       |     __|R P |  |                 |  |
  3744.            |       |__  |  |____|  |   Window          -|---
  3745.            |          | |          |_________________|__|
  3746.            |          | |              |             |
  3747.      ______|____|__   | |              |
  3748.     |           |  |  | |              |
  3749.     | ViewPort     |  | |              |
  3750.  ---|              |- | |              |
  3751.     |______________|  | |              |
  3752.                       | |              |
  3753.         ______|_|_____      ___|___
  3754.            |              |    |       |
  3755.                |  BitMap      | <--| R P   |
  3756.            |______________|    |_______|
  3757.  
  3758.  
  3759.                                 PAGE 166
  3760.  
  3761. -----------------------------------------------------------------------------
  3762.  
  3763. The most elemental part if a display, the ViewPort, is controlled by 
  3764. Intuition with the help of a screen. The screen and window are displayed
  3765. through a private RastPort in a shared video RAM, the bit-planes.
  3766.  
  3767. We still hane not explained the Layer, Colormap and RasInfo components. 
  3768.  
  3769. Before we continue our study of the graphics system, we have one more point
  3770. to discuss. There is an additional data structure called VIEW that seems to 
  3771. appear out of nowhere. 
  3772.  
  3773.                                 PAGE 167
  3774.         
  3775. -----------------------------------------------------------------------------
  3776.  
  3777. 4.4 VIEW: THE GRAPHIC BRAIN.
  3778.  
  3779. It is not surprising that the address of View, or even it's name has not
  3780. appeared yet. View is the contact point between the graphic software and
  3781. the graphic hardware of the Amiga. It is where everything begins. You can 
  3782. obtain the address of View by calling an Intuition function name 
  3783. ViewAddress. 
  3784.  
  3785.         DECLARE FUNCTION ViewAddress& LIBRARY
  3786.         LIBRARY "intuition.library"
  3787.  
  3788.         view& = ViewAddress&
  3789.  
  3790. NOTE : Remember that the Intuition routine ViewPortAddress provides you 
  3791. with the address of the ViewPort where your actual output window is 
  3792. located:        
  3793.         
  3794.         DECLARE FUNTION ViewPortAddress& LIBRARY
  3795.         LIBRARY "intuition.library"
  3796.         
  3797.         vp& = ViewPortAddress&(WINDOW(7))
  3798.  
  3799. Here is the View data structure :
  3800.  
  3801. Data structure : View/graphics/18 bytes.
  3802.  
  3803. Offset  Type    Description
  3804. ------- ------- -------------------------------------------------
  3805. +000    Long    Pointer to the first ViewPort.
  3806. +004    Long    LongFrame Copper List.
  3807. +008    Long    ShortFrame Copper List.
  3808. +012    Word    DyOffset
  3809. +014    Word    DxOffset
  3810. +016    Word    Mode
  3811.  
  3812. Although View doesn't seem like an essential part of the graphics system,
  3813. the entire display (including all screens) is dependant on it. A detailed
  3814. description of the data fields follows :
  3815.  
  3816. OFFSET 0 : NEXT VIEWPORT
  3817.  
  3818. This offset contains the address pointer to the first ViewPort structure
  3819. of the display. From that structure you can obtain the addresses of further
  3820. ViewPorts, if there are any.
  3821.         
  3822.                                 PAGE 168
  3823.         
  3824. ---------------------------------------------------------------------------
  3825.  
  3826. OFFSET 4 AND 8 : COPPER LISTS.
  3827.  
  3828. We have dealt with Copper lists before when discussing the ViewPorts. Just 
  3829. as the Copper list of the ViewPorts is responsible for the drawing region
  3830. of the ViewPort, the Copper list controls the entire display (or in other
  3831. words ; all the ViewPorts). A normal display requires only the LongFrame
  3832. list. The second Copper list is only necessary when using the Interlace
  3833. mode.
  3834.  
  3835. The rest of the fields are self explanatory since they have exactly the 
  3836. same funtions as the same name fields in the ViewPort.
  3837.  
  3838. Now that we've added View to our explanation of the graphics system, we
  3839. have covered the most important components. The connection between 
  3840. hardware and intuition is complete.
  3841.  
  3842.  
  3843.         __|_____________
  3844.                |                | 
  3845.                |  Screen        |<----------------
  3846.         ___|                |                 |  
  3847.            |   |                |------           |
  3848.            |   |________________|      |          |
  3849.            |       |    |   ____       |          |
  3850.            |       |    |__|    |   ___|__________|__|__
  3851.            |       |     __|R P |  |                 |  |
  3852.            |       |__  |  |____|  |   Window          -|---
  3853.            |          | |          |_________________|__|
  3854.            |          | |              |             |
  3855.      ______|____|__   | |              |
  3856.     |           |  |  | |              |
  3857.     | ViewPort     |  | |              |
  3858.  ---|              |- | |              |
  3859.     |______________|  | |              |
  3860.        |              | |              |
  3861.   _____|____    ______|_|_____      ___|___
  3862.  |          |  |              |    |       |
  3863.  |  View    |  |  BitMap      | <--| R P   |
  3864.  |__________|  |______________|    |_______|
  3865.        |         | | | | | |         |
  3866.        |                 |
  3867.   _____|_______________             |
  3868.  | Instructions Copper |         |
  3869.  |_____________________|         |
  3870.        |                  |
  3871.  ______|_____________________________|____
  3872. |__________________              |
  3873. |           |              |
  3874. |    COPPER        |----> Blitter         |
  3875. |           |      other special   |
  3876. |           |----> CoProcessors    |
  3877. |__________________|______________________| 
  3878.  
  3879.                                 PAGE 169
  3880.  
  3881. -----------------------------------------------------------------------------
  3882.  
  3883. Before we continue with the graphic system, we need to test our model of
  3884. the system. Since we have now advanced far enough, we can create our
  3885. own display. There are several functions from the graphic libraries that
  3886. we need.
  3887.  
  3888.         InitView()
  3889.         InitVPort()
  3890.         GetColorMap()
  3891.         InitBitMap()
  3892.         AllocRaster()
  3893.         LoadRGB4()
  3894.         MakeVPort()
  3895.         MrgCop()
  3896.         LoadView()
  3897.         FreeRaster()
  3898.         FreeColorMap()
  3899.         FreeVPortCopLists()
  3900.         FreeCprList()
  3901.  
  3902. In the following program we are going to demostrate all the steps required
  3903. to create a simple display using a ViewPort. Use our program as a model 
  3904. that shows the correct programming methods. Since copper programming is the
  3905. subject of the next chapter this program is a good practising excercise.
  3906.         
  3907.         
  3908.         '################################################
  3909.         '# 
  3910.         '# Section : 4.4
  3911.         '# Program : Graphic Primitive Display.
  3912.         '# Date    : 01/01/87
  3913.         '# Author  : tob
  3914.         '# Version : 1.0
  3915.         '#
  3916.         '#################################################
  3917.         
  3918.         'Demonstrates the creation of a graphiv display on the Amiga
  3919.         'using the "graphic primitives", the base commands of the 
  3920.         'Graphic Library. This screen is Hires with one bitplane.        
  3921.         'The contents of the first bit-plane of this screen is copied
  3922.         'to the new display.
  3923.         
  3924.         PRINT "Searching for .bmap file .... "
  3925.         
  3926.         'GRAPHICS library
  3927.         DECLARE FUNCTION AllocRaster& LIBRARY
  3928.         DECLARE FUNCTION GetColorMap& LIBRARY
  3929.         
  3930.         
  3931.                                 PAGE 170
  3932.  
  3933. -----------------------------------------------------------------------------
  3934.  
  3935.         'FreeRaster()
  3936.         'FreeColorMap()
  3937.         'FreeVPortCopLists()
  3938.         'FreeCprList()
  3939.         'InitView()
  3940.         'InitVPort()
  3941.         'InitBitMap()
  3942.         'LoadRGB4()
  3943.         'MakeVPort()
  3944.         'MrgCop()
  3945.         'LoadView()
  3946.         
  3947.         'EXEC library
  3948.         DECLARE FUNCTION AllocMem& LIBRARY
  3949.         'FreeMem()
  3950.         
  3951.         'INTUITION library
  3952.         DECLARE FUNCTION ViewAddress& LIBRARY
  3953.          
  3954.         LIBRARY "exec.library"
  3955.         LIBRARY "graphic.library"
  3956.         LIBRARY "intuition.library"
  3957.  
  3958.         init:  'Define screen parameters.
  3959.             wide% = 640
  3960.             height% = 200
  3961.             depth%  = 1
  3962.             o.bitplane1& = PEEKL(PEEKL(WINDOW(8)+4)+8)
  3963.         
  3964.             'Store our view pointer to enable us to 
  3965.             'return to it later.
  3966.             oldview& = ViewAddress&
  3967.  
  3968.             'Reserve memory for required structures.
  3969.             ' View - Brain of Displays.
  3970.             view&    = 18
  3971.             GetMemory view&
  3972.         
  3973.             ' ViewPort - Our Screen.
  3974.             viewport& = 40
  3975.             GetMemory viewport&
  3976.         
  3977.             ' BitMap - Manager of bit-planes.
  3978.             bitmap&   = 40
  3979.             GetMemory bitmap&
  3980.         
  3981.             ' RasInfo - Information about the ViewPort.
  3982.             RasInfo&  = 12
  3983.             GetMemory RasInfo&
  3984.  
  3985.             'Prepare View and ViewPort for use.
  3986.             CALL InitView(view&)
  3987.             CALL InitVPort(viewport&)
  3988.  
  3989.             'Hi-res.
  3990.             hires& = &H8000
  3991.             POKEW viewport&+32+hires&
  3992.  
  3993.             'Place ViewPort is View.
  3994.             POKEL view&,viewport&
  3995.  
  3996.                                 PAGE 171
  3997.  
  3998. -----------------------------------------------------------------------------
  3999.        
  4000.             'Setup Color Table.
  4001.             colroMap& = GetColorMap&(2)
  4002.             If colorMap& = 0 THEN RETURN
  4003.                         
  4004.             'Fill ViewPort with our Parameters.
  4005.             POKEW viewport&+24,wide%
  4006.             POKEW viewport&+26,height%
  4007.         
  4008.             'Place RasInfo in ViewPort
  4009.             POKEL viewport&+36,RasInfo&
  4010.             
  4011.             'Place color table in the ViewPort.
  4012.             POKEL viewport&+4,colorMap&
  4013.         
  4014.             'Fill bitmap structure with our Parameters.
  4015.             CALL InitBitMap(bitmap&,depth%,wide%,height%)
  4016.             
  4017.             'Get a bitplane.
  4018.             plane&   = AllocRaster&(wide%,height%)
  4019.             IF plane& = 0 THEN ERROR 7
  4020.         
  4021.             'Place bitplane in Bitmap.
  4022.             POKEL bitmap&+8,plane&
  4023.         
  4024.             'Place bitmap in RasInfo
  4025.             POKEL RasInfo&+4,bitmap&
  4026.         
  4027.             'Define colours.
  4028.             red$         = CHR$(15)+CHR$(0)
  4029.             black$       = CHR$(0) +CHR$(0)
  4030.             colortable$  = red$ + black$
  4031.         
  4032.             'Load colours into colour table.
  4033.             CALL LoadRGB4(viewport&,SADD(colortable$),2)
  4034.         
  4035.             'Constuct Copper instruction List.
  4036.             CALL MakeVPort(view&,viewport&)
  4037.             CALL MrCop(view&)
  4038.         
  4039.             ' Load new display into copper.
  4040.             CALL LoadView(view&)
  4041.             
  4042.             'Play with the Display
  4043.             BEEP
  4044.             size& = wide% * height% / 8
  4045.         
  4046.             FOR loop& = 0 TO size&-1
  4047.                 POKE plane&+loop&,PEEK(o.bitplane1&+loop&)
  4048.             NEXT loop&
  4049.             BEEP
  4050.             
  4051.             'Restore Old Copper List.
  4052.             CALL LoadView(oldview&)
  4053.             
  4054.                                 PAGE 172
  4055.         
  4056. -----------------------------------------------------------------------------
  4057.         
  4058.             'Cleanup: Return Memory for bit plane.
  4059.             CALL FreeRaster(plane&,wide%,height%)
  4060.             ' Release Color Table
  4061.             CALL FreeColorMap(colormap&)
  4062.             ' Release Interim ViewPort lists.
  4063.             CALL FreeVPortCopLists(viewport&)
  4064.             ' Release Copper Instruction List.
  4065.             copperlist& = PEEKL(view&+4)
  4066.             CALL FreeCprList(copperlist&)
  4067.             
  4068.             ' Release Structure Memory.
  4069.             FreeMemory view&
  4070.             FreeMemory viewport&
  4071.             FreeMemory RasInfo&
  4072.             FreeMemory bitmap&
  4073.         
  4074.             ' AND THAT'S  IT ...
  4075.             LIBRARY CLOSE
  4076.             END
  4077.             
  4078.         SUB GetMemory(size&) STATIC
  4079.             opt&         = 2^0+2^1+2^16
  4080.             RealSize&    = size& + 4
  4081.             size&        = AllocMem&(RealSize&, opt&)
  4082.             IF size&     = 0 THEN ERROR 255
  4083.             POKEL size&,RealSize&
  4084.             size& = size&+4
  4085.         END SUB
  4086.         
  4087.         SUB FreeMemory(add&) STATIC
  4088.             add&       = add&-4
  4089.             RealSize& = PEEKL(add&)
  4090.             CALL FreeMem(add&,RealSize&)
  4091.         END SUB
  4092.         
  4093.         
  4094. THE PROGRAM.
  4095. ------------
  4096.  
  4097. The first step in our program is to choose what kind of display we want
  4098. to create (how wide and how high). Our choice is a high-res screen with 
  4099. a standard resolution of 640*200 pixels and a depth of one bitplane.
  4100.         
  4101. To be able to return to our original display we must store the addresses
  4102. of our structure in several variables. The intuition function 
  4103. ViewAddress provides the requierd pointers.
  4104.         
  4105. To create our display we use the following structures:
  4106.         
  4107.         View (18 bytes)
  4108.         ViewPort (40 bytes)
  4109.         BitMap (40 bytes)
  4110.         RasInfo (12 bytes)
  4111.         
  4112. The View structure forms the brain of our future display. There is only
  4113. one active view and from this view you can have any number of ViewPort
  4114. branches.
  4115.                                 
  4116.                                 PAGE 173
  4117.         
  4118. -----------------------------------------------------------------------------
  4119.         
  4120. View and ViewPort must be created ready to use. InitView fills the View
  4121. structure with the standard values, which automatically sets the View
  4122. structure to appear about a half inch from the edge of the screen. 
  4123. InitVPort does the same thing with the ViewPort. It is normally set for
  4124. lo-res and the pointer for the next ViewPort is set to zero because
  4125. usually there are no additional ViewPorts.
  4126.         
  4127. Now we have to make a connection between View and ViewPort. To do this, we
  4128. use the first field of the View structure to store the address of the first
  4129. (and only) ViewPort structure.
  4130.         
  4131. Next we must have a colour table that will later be used by our screen.
  4132. GetColorMap will take care of this. 
  4133.         
  4134. Then we store the resolution for our ViewPort and the RasInfo block is 
  4135. placed in the ViewPort. Now we make the Bit-Map structure ready for use
  4136. by using InitBitMap(). We write the address of our bitplane into the
  4137. Bit-map structure.
  4138.         
  4139. Next we write the address of the Bitmap into the RasInfo structure. Then
  4140. we use LoadRGB4 to store the colours to the ViewPort.
  4141.         
  4142. Now that all the required data has been stored, our display is ready to
  4143. use. The Amiga creates the instructions for the graphic processor from
  4144. our information with the following steps : 1.) the function MakeVPort
  4145. creates the Copper list from the data in the viewports and writes the 
  4146. pointer for this list into the ViewPort, and 2.) the function MrgCop 
  4147. integrates the instructions of our ViewPort with those of all the displays
  4148. (we have only one ViewPort).
  4149.         
  4150. The completed Copper list is stored in View. A list of copper commands has
  4151. been created from the data and will be used for our display. We just have 
  4152. to send the commands to the copper and our new display will appear. This 
  4153. action is performed by LoadView and immediately we see our bright red
  4154. display.        
  4155.         
  4156. To show you that this is a fully functional display, we copy the first 
  4157. bit-plane of the workbench screen to it. This takes a few moments.
  4158.         
  4159. Everything worked, but now we want to get back to the original display. 
  4160. Since we stored the address for our old View, we shouldn't have any 
  4161. problems. We can use LoadView to send the old copper lists to the Copper
  4162. and return to the original.        
  4163.         
  4164. Althouh the demonstration is over, we still need to "cleanup" because
  4165. the display has used up a lot of memory that we will want to release again.
  4166.                         
  4167.                                 PAGE 174
  4168.         
  4169. ----------------------------------------------------------------------------
  4170.         
  4171. 4.5 COPPER PROGRAMMING.
  4172.         
  4173. The Copper has just demonstrated how powerful it is. We are going to take
  4174. advantage of that power with our next program, which will use a technique
  4175. known as double buffering.
  4176.         
  4177.                 --------------------------------------------
  4178.         
  4179. 4.5.1 DOUBLE BUFFERING FOR LIGHTNING FAST GRAPHICS.
  4180.         
  4181. The drawing speed of the Amiga does not affect the Copper because the
  4182. Copper operates independantly at full speed. Because of this you can
  4183. amaze the users of your programs with lightning fast graphics created 
  4184. with double buffering. To create this effect, show the user a display
  4185. on which nothing is happening. While the user stares at this boring 
  4186. display, build your graphics in a second, invisible display. When your
  4187. graphics are complete, switch on the second display and your graphics 
  4188. will instantly appear on the screen.        
  4189.         
  4190. We will now explain how this works. The pointer to the Copper lists of 
  4191. the old display are read from View and stored. The pointer in View is
  4192. erased. Now a new bit-map with new bit-planes is prepared for the second
  4193. display. MakeVPort and MrgCop are used to generate the new copper lists, 
  4194. which are then stored. To switch from one display to the other we just 
  4195. write the new pointer to the View structure and use LoadView to activate
  4196. it.        
  4197.         
  4198. Again we have designed a small program package. If consists of the 
  4199. following SUB programs:
  4200.         
  4201.         MakeDoubleBuffer
  4202.         DoubleBufferOn
  4203.         DoubleBufferOff
  4204.         AbortDoubleBuffer
  4205.         transmit
  4206.         
  4207.                                 PAGE 175
  4208.         
  4209. -----------------------------------------------------------------------------
  4210.         
  4211.         
  4212.         '################################################
  4213.         '#
  4214.         '# Section : 4.5.1
  4215.         '# Program : Double Buffered Display.
  4216.         '# Author  : tob
  4217.         '# Version : 1.0
  4218.         '#
  4219.         '################################################
  4220.         '
  4221.         ' This program creates a second screen that works
  4222.         ' as a backup buffer for the normal screen.
  4223.         '
  4224.         
  4225.         PRINT "Searching for .BMAP file ............"
  4226.         
  4227.         'GRAPHICS-library
  4228.         DECLARE FUNCTION BltBitMap& LIBRARY
  4229.         DECLARE FUNCTION AllocRaster& LIBRARY
  4230.         'FreeRaster()
  4231.         'MakeVPort()
  4232.         'MrgCop()
  4233.         'LoadView()
  4234.         'FreeCprList()
  4235.         
  4236.         'EXEC-library
  4237.         DECLARE FUNCTION AllocMem& LIBRARY
  4238.         'FreeMem()
  4239.         'CopyMem()
  4240.         
  4241.         'INTUITION-library
  4242.         DECLARE FUNCTION ViewPortAddress& LIBRARY
  4243.         DECLARE FUNCTION ViewAddress& LIBRARY
  4244.         
  4245.         LIBRARY "intuition.library"
  4246.         LIBRARY "graphics.library"
  4247.         LIBRARY "exec.library"
  4248.         
  4249.         init:    CLS
  4250.             PRINT "WITHOUT DOUBLE BUFFERING!"
  4251.             FOR t = 1 TO 20
  4252.                 PRINT STRING$(80,"+")
  4253.             NEXT t
  4254.             FOR t = 1 TO 20
  4255.                 x%  = RND(1) * 600
  4256.                 y%  = RND(1) * 150
  4257.                 r%  = RND(1) * 100
  4258.                 CIRCLE (x%,y%),r%
  4259.             NEXT t
  4260.             CLS
  4261.             PRINT "AND NOW WITH DOUBLE BUFFERING!!!"
  4262.             MakeDoubleBuffer
  4263.             DoubleBufferOn
  4264.             FOR t = 1 TO 20
  4265.                 PRINT STRING$(80,"+")
  4266.             NEXT t
  4267.             transmit
  4268.             LOCATE 1,1
  4269.         
  4270.                                    PAGE 176
  4271.         
  4272. -----------------------------------------------------------------------------
  4273.         
  4274.             FOR t = 1 TO 20
  4275.                 x% = RND(1) * 600
  4276.                 y% = RND(1) * 150
  4277.                 r% = RND(1) * 100
  4278.                 CIRCLE (x%,y%),r%
  4279.             NEXT t
  4280.             transmit
  4281.             LOCATE 5,10
  4282.             LINE (38,29)-(442,67),3,b
  4283.             PRINT "Even this works!"
  4284.             PRINT "Double Buffering = Backup Display"
  4285.             PRInt "These are two separate screen that"
  4286.             PRINT "are switched back and forth"
  4287.             FOR loop% = 1 TO 15
  4288.                 DoubleBufferOn
  4289.                 FOR T = 1 TO 1000: NEXT t
  4290.                 DoubleBufferOff
  4291.                 FOR T = 1 TO 1000: NEXT t
  4292.             NEXT loop%
  4293.             PRINT
  4294.             PRINT "PRESS THE LEFT MOUSEBUTTON!"
  4295.             SLEEP:SLEEP
  4296.             AbortDoubleBuffer
  4297.             LIBRARY CLOSE
  4298.             END
  4299.         
  4300.         
  4301.     SUB MakeDoubleBuffer STATIC
  4302.         '* Create second display.
  4303.         SHARED TargetBitmap&, rasInfo&, SourceBitMap&, view&
  4304.         SHARED bufferx%, buffery%, vp&
  4305.         SHARED home1&, home2&, guest1&, guest2&
  4306.         view&           = ViewAddress&
  4307.         vp&             = ViewPortAddress&(WINDOW(7))
  4308.         rasiInfo&       = PEEKL(vp&+36)
  4309.         SourceBitMap&   = PEEKL(rasInfo&+4)
  4310.         opt&            = 2^0 + 2^1 + 2^16
  4311.         TargetBitmap&   = AllocMem&(40,opt&)
  4312.         
  4313.         '* Copy Bitmaps
  4314.         IF TargetBitmap& = 0 THEN ERROR 7
  4315.         '* NOTE: FOR KICKSTART VERSION 1.2 AND ABOVE.
  4316.         '* FOR 1.0 AND 1.1 USE LINES BELOW.
  4317.         '*
  4318.         '*
  4319.         '* For loop& = 0 TO 40 STEP 4
  4320.         '*   POKEL TargetBitmap&+loop&,PEEKL(SourceBitMap&+loop&)
  4321.         '* NEXT loop&
  4322.         '
  4323.         
  4324.         CALL CopyMem(SourceBitMap&,TargetBitmap&,40)
  4325.         
  4326.         ' Get Planes.
  4327.         bufferx%     = PEEKW(SourceBitMap&)*8
  4328.         buffery%     = PEEKW(SourceBitMap&+2)
  4329.         
  4330.                                 PAGE 177
  4331.         
  4332. -----------------------------------------------------------------------------
  4333.         
  4334.         depth%      = PEEK(SourceBitMap&+5)
  4335.         FOR loop% = 0 TO depth% - 1
  4336.             plane&(loop%) = AllocRaster&(bufferx%,buffery%)
  4337.             IF plane&(loop%) = 0 THEN ERROR 7
  4338.             POKEL TargetBitmap&+8+loop%*4,plane&(loop%)
  4339.         NEXT loop%
  4340.         
  4341.         'Copy active display to buffer.
  4342.         plc% = BltBitMap&(SourceBitMap&,0,0,TargetBitmap&,0,0,bufferx%
  4343.     buffery%,200,255,0)
  4344.         IF plc%<>depth% THEN ERROR 17
  4345.         
  4346.         ' Store original Copper List
  4347.         home1& = PEEKL(view&+4)
  4348.         home2& = PEEKL(view&+8)
  4349.         
  4350.         'Generate Second Copper List
  4351.         POKEL view&+4,0
  4352.         POKEL view&+8,0
  4353.         POKEL rasInfo&+4,TargetBitmap&
  4354.         CALL MakeVPort(view&,vp&)
  4355.         CALL MrgCop(view&)
  4356.         CALL LoadView(view&)
  4357.         guest1& = PEEKL(view&+4)
  4358.         guest2& = PEEKL(view&+8)
  4359.         
  4360.         'Reset
  4361.         POKEL rasInfo&+4,SourceBitMap&
  4362.         POKEL view&+4,home1&
  4363.         POKEL view&+8,home2&
  4364.         CALL LoadView(view&)
  4365.     END SUB
  4366.         
  4367.         
  4368.     SUB DoubleBufferOn STATIC
  4369.         '* Activate new copper list.
  4370.         SHARED view&, guest1&, guest2&
  4371.         SHARED rasInfo&, TargetBitmap&
  4372.         POKEL view&+4,guest1&
  4373.         POKEL view&+8,guest2&
  4374.         CALL LoadView(view&)
  4375.     END SUB
  4376.         
  4377.     SUB DoubleBufferOff STATIC
  4378.         '* ACtivate old Copper List
  4379.         SHARED view&, home1&, home2&
  4380.         SHARED rasInfo&, SourceBitMap&
  4381.         POKEL view&+4,home1&
  4382.         POKEL view&+8,home2&
  4383.         CALL LoadView(view&)
  4384.     END SUB
  4385.         
  4386.     SUB transmit STATIC 
  4387.         'Copy old display to the new buffer.
  4388.         SHARED SourceBitMap&,TargetBitmap&,bufferx%,buffery%
  4389.         plc% = BltBitMap&(SourceBitMap&,0,0,TargetBitmap&,0,0,bufferx%,
  4390.     buffery%,200,255,0)
  4391.     END SUB
  4392.         
  4393.                                 PAGE 178
  4394.         
  4395. -----------------------------------------------------------------------------
  4396.         
  4397.         SUB AbortDoubleBuffer STATIC
  4398.         SHARED rasInfo&, view&, TargetBitmap&
  4399.         SHARED vp&, bufferx%, buffery%
  4400.         SHARED home1%, home2%, guest1%, guest2%
  4401.         
  4402.         '* Restore Old Display and VPort copperlists.
  4403.         POKEL view&+4,home1&
  4404.         POKEL view&+8,home2&
  4405.         CALL MakeVPort(view&,vp&)
  4406.         CALL MrgCop(view&)
  4407.         CALL LoadView(view&)
  4408.         
  4409.         '* Delete new VPort Copper List Set
  4410.         CALL FreeCprList(guest1&)
  4411.         
  4412.         '* Delete Second Copper list set.
  4413.         IF guest2&<>0 THEN CALL FreeCprList(guest2&)
  4414.         add& = TargetBitmap&+8
  4415.         pl& = PEEKL(add&)
  4416.     
  4417.         '* Delete BitPlanes and BitMap
  4418.         WHILE pl&<>0
  4419.             CALL FreeRaster(pl&,bufferx%,buffery%)
  4420.             add& = add&+4
  4421.             pl&  = PEEKL(add&)
  4422.         WEND
  4423.         CALL FreeMem(TargetBitmap&,40)
  4424.     END SUB
  4425.         
  4426.         
  4427. DESCRIPTION: 
  4428.  
  4429. You switch the double buffer system on with the command:
  4430.  
  4431.         MakeDoubleBuffer
  4432.  
  4433. The double buffer is used to create the invisible display. This command
  4434. can only be used once. When you are ready to start, execute:
  4435.         
  4436.         DoubleBufferOn
  4437.  
  4438. This command activates the hidden display. Your old display, where you are
  4439. drawing, becomes invisible. Now you can take your time to create you
  4440. graphics, no drawing can be seen on the screen.
  4441.         
  4442. As soon as your graphic is complete you only have to call:
  4443.         
  4444.         transmit
  4445.         
  4446.                                 PAGE 179
  4447.         
  4448. -----------------------------------------------------------------------------
  4449.         
  4450. to display the contents of the hidden display (in other words, to send your
  4451. graphic to the visible screen). You can use the transmit command as often
  4452. as desired.
  4453.         
  4454. When you want to quickly switch to an unbuffered display simply call:
  4455.         
  4456.         DoubleBufferOff
  4457.         
  4458. All graphic and print commands will, from this point on, appear immediately
  4459. on the screen. With DoubleBufferOn, you can activate the buffered system
  4460. again.        
  4461.         
  4462. Should you desire to leave the system entirly because your program is 
  4463. finished or you are tired of double buffer drawing, then use:
  4464.         
  4465.         AbortDoubleBuffer
  4466.         
  4467. All memory areas used for the buffer displays are returned to the system.
  4468.         
  4469.                 --------------------------------------------
  4470.         
  4471. 4.5.2  PROGRAMMING THE COPPER YOURSELF.
  4472.         
  4473. So far we have let the Amiga create the copper lists for us, from the data
  4474. we provided. Another possibility is to program the copper ourselves.
  4475.         
  4476. Before you do this, you need to understand the Copper functions. The copper
  4477. works very closely with the electronic beams of the display. These 
  4478. electronic beams scan from the upper left hand corner to the lower right
  4479. hand corner of the screen sixty (50 uk) times a second.        
  4480.         
  4481. The copper is capable of waiting for this electronic beam to reach a 
  4482. specific position. This is handled by the WAIT instruction of the 
  4483. processor. The instruction requires a Y and X coordinate and tells the 
  4484. Copper to wait until the electronic beam has reached this coordinate.
  4485. Until this occurs, the Copper will not process any more instructions.
  4486.         
  4487. The MOVE instruction allows the copper to directly address hardware 
  4488. registers in the special purpose chips (the hardware registers are detailed
  4489. in appendix C). The MOVE instruction requires an offset for the hardware
  4490. register and a value to store in the register.        
  4491.         
  4492. The third and last instruction for the Copper is named SKIP. This 
  4493. instruction is used to actually skip past items in the copper list.
  4494.         
  4495.         
  4496.                                 PAGE 180
  4497.         
  4498. -----------------------------------------------------------------------------
  4499.         
  4500. Writing a Copper list for an entire display would be a very tedious job.
  4501. Fortunately, this isn't necessary because most of the work can be 
  4502. accomplished easily by using MakeVPort. However, if you want to add your
  4503. own Copper instructions to the Copper list for the displays, there is 
  4504. another method. In the structure of every ViewPort you will find a pointer
  4505. for a user copper list. When you want to integrate your own instructions
  4506. with a display, create a stand alone Copper list with the desired commands.
  4507. Then store the starting address of your list to the User Copper list 
  4508. pointer. Now you can continue as usual. MakeVPort links the user list to
  4509. the display list of the viewport, MrgCop links this list to the entire
  4510. list in View and LoadView activates the manipulated copper lists.
  4511.         
  4512. We will now show you how to create your own Copper list. The next program
  4513. contains 4 SUB programs for this purpose.
  4514.         
  4515.         InitCop
  4516.         ActiCop
  4517.         WaitC
  4518.         MoveC
  4519.         
  4520. First you need to create a data structure name UCopList. This structure
  4521. requires 12 bytes of memory which is reserved with InitCop.
  4522.         
  4523. We can program the user list with the commands MoveC and WaitC (skip is
  4524. not necessary for our application).
  4525.    
  4526. The call to the wait command looks like this:
  4527.         
  4528.         WaitC y%,x%
  4529.         
  4530. The Y coordinate, which the Copper waits for, must be first. WaitC 
  4531. requires that this coordinate is first because it is easier to combine
  4532. the copper lists using MrgCop if they all have the same order.
  4533.         
  4534. MoveC can write any desired 16 bit value to a hardware register. In this
  4535. chapter we use only a few of the many available registers. The complete 
  4536. register list is located in Appendix C. Here is the call :
  4537.         
  4538.         MoveC register%, value%
  4539.         
  4540.         register%     : Offset of the desired hardware register.
  4541.         value%        : 16 bit value.
  4542.         
  4543. Here is a selection of the most important hardware registers we are 
  4544. going to use:
  4545.         
  4546.         
  4547.                                 PAGE 181
  4548.         
  4549. -----------------------------------------------------------------------------
  4550.         
  4551.         Register    Meaning
  4552.         ---------   ------------------------------------------------
  4553.            384      Colour Register 0 (Background colour)
  4554.            386      Colour Register 1 (Drawing Colour)
  4555.            388      Colour Register 2
  4556.           (...)
  4557.            444      Colour Register 30
  4558.            446      Colour Register 30
  4559.         -------------------------------------------------------------
  4560.         
  4561. Now we can add to our user Copper list. After calling InitCop you can 
  4562. call as many MoveC's and WaitC's as you like. However, you must make
  4563. sure that your WaitC's correspond with the screen coordinates you are 
  4564. calling. The top left hand corner of the display is at (0,0). This is
  4565. where the electronic beam starts. Your WaitC coordinates must be in 
  4566. ascending X and Y coordinate sequence.
  4567.         
  4568. When your user Copper list is finished, it is linked to the existing display
  4569. with ActiCop. Your assigments will then be executed by the copper.
  4570.         
  4571. In our example program, we open our new screen. In order to return the
  4572. memory used by our copper instructions (including those in our reserved
  4573. user list), we simply close the Intuition screen. Intuition automatically
  4574. takes care of this. Do not attempt to create user instructions in the 
  4575. Workbench screen because when the instructions are executed, there will be
  4576. no way to restore the normal display and release the assigned memory.
  4577.         
  4578. The following program is an example of Copper programming basics.
  4579.         
  4580.         '##############################################
  4581.         '#
  4582.         '# Section: 4.5.2
  4583.         '# Program: Copper Raster Interrupt.
  4584.         '# Date   : 12/15/86
  4585.         '# Author : tob
  4586.         '# Version: 1.0
  4587.         '#
  4588.         '###############################################
  4589.         
  4590.         ' Demonstrates programming the Amiga graphic
  4591.         ' co-processor (copper) from AmigaBASIC
  4592.         
  4593.         PRINT "Searching for .BMAP file ..........."
  4594.         
  4595.         'INTUITION-library
  4596.         DECLARE FUNCTION ViewAddress& LIBRARY
  4597.         DECLARE FUNCTION ViewPortAddress& LIBRARY
  4598.         
  4599.         
  4600.                                 PAGE 182
  4601.         
  4602. -----------------------------------------------------------------------------
  4603.         
  4604.         'RethinkDisplay()
  4605.         
  4606.         'EXEC-library
  4607.         DECLARE FUNCTION AllocMem& LIBRARY
  4608.         'FreeMem()
  4609.         
  4610.         'GRAPHICS-library
  4611.         'CWait()
  4612.         'CMove()
  4613.         'CBump()
  4614.         
  4615.         LIBRARY "intuition.library"
  4616.         LIBRARY "graphics.library"
  4617.         LIBRARY "exec.library"
  4618.         
  4619.     pre: CLS
  4620.         SCREEN 1,640,200,2,2
  4621.         WINDOW 2,"COPPER!",(0,0)-(630,186),16,1
  4622.         PRINT "Raster Interrupt through Copper programming:A Split Screen!"
  4623.         
  4624.     init:
  4625.         kolorregister%    = 384
  4626.         red%              = 15,'0...15
  4627.         green%            = 4 ,   '0 to 15'
  4628.         blue%             = 4 ,   '0 .... 15'
  4629.         kolorvalue%       = red%*2^8+green%*2^4+blue%
  4630.         yCoordinate%      = 100
  4631.         xCoordinate%      = 20
  4632.         
  4633.     main:
  4634.         InitCop
  4635.         WaitC yCoordinate%, xCoordinate%
  4636.         moveC kolorregister%, kolorvalue%
  4637.         ActiCop
  4638.         
  4639.         PRINT " Press a Key ! "
  4640.         WHILE INKEY$ = "":WEND
  4641.         
  4642.         WINDOW CLOSE 2
  4643.         SCREEN CLOSE 1
  4644.         
  4645.     endprog:
  4646.         LIBRARY CLOSE
  4647.         END
  4648.         
  4649.     SUB InitCop STATIC
  4650.         SHARED UCopList&
  4651.         opt&         = 2^0+2^1+2^16
  4652.         UCopList&    = AllocMem&(12,opt&)
  4653.         IF UCopList& = 0 THEN ERROR 7
  4654.     END SUB
  4655.         
  4656.     SUB ActiCop STATIC
  4657.         SHARED UCopList&
  4658.         waitC 10000,256
  4659.         
  4660.                                 PAGE 183
  4661.         
  4662. -----------------------------------------------------------------------------
  4663.         
  4664.         viewport& = ViewPortAddress&(WINDOW(7))
  4665.         POKEL viewport&+20,UCopList&
  4666.         CALL RethinkDisplay
  4667.     END SUB
  4668.         
  4669.     SUB waitC(y%,x%) STATIC
  4670.         SHARED UCopList&
  4671.         CALL CWait(UCopList&,y%,x%)
  4672.         CALL CBump(UCopList&)
  4673.     END SUB
  4674.         
  4675.     SUB moveC(reg%,value%) STATIC
  4676.         SHARED UCopList&
  4677.         CALL CMove(UCopList&,reg%,value%)
  4678.         CALL CBump(UCopList&)
  4679.     END SUB
  4680.         
  4681.         
  4682. SUB program descriptions:
  4683.         
  4684. InitCop :
  4685.         The exec function AllocMem assigns a 12 byte memory area for the
  4686.         UCopList data structure.
  4687.         
  4688. WaitC   :
  4689.         A wait instruction is placed in the user list. The graphic library
  4690.         command CWait, also called CBump(), raises the internal pointer
  4691.         for the user list.
  4692.         
  4693. MoveC   :
  4694.         Calls the function CMove, from the graphic library, which places
  4695.         a move instruction in the user list. CBump() raises the user list
  4696.         pointer again.
  4697.         
  4698. ActiCop :
  4699.         a last WaitC is placed in the user list. This wait is for a screen
  4700.         position that the electron beam will never reach. This assignment
  4701.         closes the list and equals the macro CEND.
  4702.         
  4703. The address of our user list is written to the appropriate pointer in 
  4704. ViewPort for the desired screen. The Intuition function RethinkDisplay
  4705. generates the new copper list for View and sends it into the copper. The
  4706. new display then appears.        
  4707.         
  4708. At the end, the screen is closed and the copper list is removed from the
  4709. main copper list in View. All reserved memory is returned to the system.
  4710.         
  4711.         
  4712.                                 PAGE 184
  4713.         
  4714. -----------------------------------------------------------------------------
  4715.         
  4716. 4.5.3 PROGRAMMING 400 SIMULTANEOUS COLOURS.
  4717.         
  4718. We now know the principle of Copper programming. The next program is a 
  4719. small demonstration of this powerful technique. We are going to change
  4720. the background colour for each screen row by using WaitC. At the same
  4721. time we will also be changing the drawing colour for each row. With 200
  4722. screen rows per display, we finish with 400 colours on the screen at the
  4723. same time. Colours two and three remain normal.
  4724.         
  4725. NOTE : Do not use more than 1600 Copper instructions in one list.
  4726.         
  4727.         '##############################################
  4728.         '#
  4729.         '# Section: 4.5.3
  4730.         '# Program: Copper Raster Interrupt II
  4731.         '# Date   : 12/15/86
  4732.         '# Author : tob
  4733.         '# Version: 1.0
  4734.         '#
  4735.         '###############################################
  4736.         
  4737.         ' Copper programmning can create 400 different colours in the
  4738.         ' background and foreground instead of the usual 4 colors
  4739.          ' with 2 bit-planes.
  4740.         
  4741.         PRINT "Searching for .BMAP file ..........."
  4742.         
  4743.         'INTUITION-library
  4744.         DECLARE FUNCTION ViewAddress& LIBRARY
  4745.         DECLARE FUNCTION ViewPortAddress& LIBRARY
  4746.         'RethinkDisplay()
  4747.         
  4748.         'EXEC-library
  4749.         DECLARE FUNCTION AllocMem& LIBRARY
  4750.         'FreeMem()
  4751.         
  4752.         'GRAPHICS-library
  4753.         'CWait()
  4754.         'CMove()
  4755.         'CBump()
  4756.         
  4757.         LIBRARY "intuition.library"
  4758.         LIBRARY "graphics.library"
  4759.         LIBRARY "exec.library"
  4760.         
  4761.                                 PAGE 185
  4762.         
  4763. -----------------------------------------------------------------------------
  4764.     pre: CLS
  4765.         SCREEN 1,640,200,2,2
  4766.         WINDOW 2,"COPPER!",(0,0)-(630,186),16,1
  4767.         PRINT "Direct copper programming makes it possible."
  4768.         PRINT "200 background Colours!"
  4769.         PRINT "Patience Please ... Calculating Instruction lists.."
  4770.         
  4771.     init:
  4772.         kolorregister1%    = 384
  4773.         kolorregister2%    = 386
  4774.         xCoordinate%      = 20
  4775.         maxY%             = 200
  4776.         
  4777.     main:
  4778.         InitCop
  4779.         FOR loop% = 1 TO maxY%
  4780.             waitC loop%,xCoordinate%
  4781.             moveC kolorregister1%,loop%
  4782.             moveC kolorregister2%,4096-loop%
  4783.         NEXT loop%
  4784.         ActiCop
  4785.         
  4786.         ' Display text for this effect
  4787.         LOCATE 5,1
  4788.         PRINT  "The background colour shows 200 individual"
  4789.         PRINT "Colors! The text colors are also not plain"
  4790.         PRINT "anymore: 200 yellows, one per raster."
  4791.         PRINT "line. Here a useful program could"
  4792.         PRINT "take over the job instead of "
  4793.         PRINT "this useless program loop!...."
  4794.         LOCATE 15,1
  4795.         PRINT "Please press a key when you"
  4796.         PRINT "Have finished reading."
  4797.         WHILE INKEY$="": WEND
  4798.         
  4799.         LOCATE 11,1
  4800.         PRINT "Thats not going to happen this time!"
  4801.         
  4802.         FOR t=1 TO 2000: NEXT t
  4803.         CLS
  4804.         PRINT "Graphic Demo Coming up!"
  4805.         
  4806.         LINE (0,100)-(630,190),2,bf
  4807.         FOR loop% = 0 TO 630 STEP 30
  4808.             LINE (loop%*1.5,190)-(loop%,100),1
  4809.         NEXT loop%
  4810.         FOR loop% = 100 TO 190 STEP 20
  4811.             LINE (0,loop%)-(630,loop%),1
  4812.         NEXT loop%
  4813.         
  4814.         CIRCLE (300,80),120,3
  4815.         
  4816.                                 PAGE 186
  4817.         
  4818. -----------------------------------------------------------------------------
  4819.         
  4820.             PAINT (300,80),3,3
  4821.             
  4822.             CIRCLE (300,80),100,1
  4823.             PAINT (300,80),1,1
  4824.         
  4825.             CIRCLE (300,146),180,3,,,1/15
  4826.             PAINT (300,146),1,3
  4827.  
  4828.             LOCATE 1,1
  4829.             PRINT "Press a Key!"+SPACE$(40)
  4830.         WHILE INKEY$ = "":WEND
  4831.         
  4832.         WINDOW CLOSE 2
  4833.         SCREEN CLOSE 1
  4834.         
  4835.     ende:
  4836.         LIBRARY CLOSE
  4837.         END
  4838.         
  4839.     SUB InitCop STATIC
  4840.         SHARED UCopList&
  4841.         opt&         = 2^0+2^1+2^16
  4842.         UCopList&    = AllocMem&(12,opt&)
  4843.         IF UCopList& = 0 THEN ERROR 7
  4844.     END SUB
  4845.         
  4846.     SUB ActiCop STATIC
  4847.         SHARED UCopList&
  4848.         waitC 10000,256
  4849.         viewport& = ViewPortAddress&(WINDOW(7))
  4850.         POKEL viewport&+20,UCopList&
  4851.         CALL RethinkDisplay
  4852.     END SUB
  4853.         
  4854.     SUB waitC(y%,x%) STATIC
  4855.         SHARED UCopList&
  4856.         CALL CWait(UCopList&,y%,x%)
  4857.         CALL CBump(UCopList&)
  4858.     END SUB
  4859.         
  4860.     SUB moveC(reg%,value%) STATIC
  4861.         SHARED UCopList&
  4862.         CALL CMove(UCopList&,reg%,value%)
  4863.         CALL CBump(UCopList&)
  4864.     END SUB
  4865.         
  4866.         
  4867. The text displayed by the program makes the details of the changed display
  4868. clearer and more impressive. A simple graphic is created but it has a
  4869. fascinatin appearance because of the Copper programming. This graphic is
  4870. formed from more than 400 colors with only two bit-planes. After pressing
  4871. a key the normal screen appears.
  4872.         
  4873.                                 PAGE 187
  4874.         
  4875. -----------------------------------------------------------------------------
  4876.         
  4877. 4.6 THE LAYERS: SOUL OF THE WINDOWS.
  4878.         
  4879. We will continue building our picture of the graphics system. In the
  4880. RastPort structure there is a pointer to the LAYERS. Layers refer to the
  4881. independant system components of the operating system that are controlled
  4882. through the layer libraries.
  4883.         
  4884. To discover what layers are, take a look at your Amiga monitor. You 
  4885. probably cannot see the layers because of all the windows. Actually, every
  4886. window is a layer.
  4887.         
  4888. Just as the screen is simply another ViewPort, a window is just another
  4889. layer. A layer handles most of the work required to create windows. One 
  4890. problem which always occurs when a computer works with windows is that
  4891. everything you see on screen, including the screen background and windows,
  4892. is stored in the bit-planes of the bitmap. An ideal exampl of this problem
  4893. is a display that contains the screen background and many window fragments.
  4894. These windows can overlap, can be covered completely by others or can be
  4895. displayed by themselves. As soon as one window overlaps another, this must
  4896. be recorded because the overlapped portion consists of two windows divided
  4897. within the same bit-map. The layers ensure that the covered window section
  4898. is saved to another area of memory. Whenever the covered window, (or a 
  4899. portion of it) becomes visible again, the layers copy the uncovered piece
  4900. back into the screen bitmap.
  4901.         
  4902. Before we discuss this theory in more detail we are going to trap and 
  4903. display a layer for you. The following small program performs this
  4904. operation.
  4905.         
  4906.         
  4907.         '##########################################
  4908.         '#
  4909.         '# Section: 4.6
  4910.         '# Program: A layer.
  4911.         '# Date   : 01/05/87
  4912.         '# Author : tob
  4913.         '# Version: 1.0
  4914.         '#
  4915.         '###########################################
  4916.         
  4917.         ' A simple layer - the basis of every window is 
  4918.         ' generated.
  4919.         
  4920.         PRINT "Searching for .bmap files.............."
  4921.         
  4922.                                 PAGE 188
  4923.         
  4924. -----------------------------------------------------------------------------
  4925.         
  4926.         'LAYERS-library
  4927.         DECLARE FUNCTION CreateUpFrontLayer& LIBRARY
  4928.         'DeleteLayer()
  4929.         'MoveLayer()
  4930.         
  4931.         'GRAPHICS-library
  4932.         'Text()
  4933.         'Move()
  4934.         
  4935.         LIBRARY "graphics.library"
  4936.         LIBRARY "layers.library"
  4937.         
  4938.         initpars:            
  4939.             CLS
  4940.             scrAdd&               = PEEKL(WINDOW(7)+46)
  4941.             screenLayerInfo&       = scrAdd&+224
  4942.             screenBitMap&         = scrAdd&+184
  4943.             x0%                   = 10
  4944.             y0%                   = 20
  4945.             x1%                   = 400
  4946.             y1%                   = 80
  4947.             typ%                   = 1
  4948.         
  4949.         thatYou:     'can also see it
  4950.             CLS
  4951.             LINE (1,1)-(600,180),2,bf
  4952.             
  4953.         LayerHer:
  4954.             layer& = CreateUpFrontLayer(screenLayerInfo&,screenBitMap&,
  4955.  x0%,y0%,x1%,y1%,typ%,0)
  4956.         
  4957.         whatToDo:
  4958.             layerRast& = PEEKL(layer&+12)
  4959.             text$ = "This is the soul of a window: A Layer!"
  4960.             CALL Move(layerRast&,3,8)
  4961.             CALL Text(layerRast&,SADD(text$),LEN(text$))
  4962.         
  4963.         moveit:        
  4964.             dx%   = 2
  4965.             dy%   = 1
  4966.             FOR loop1% = 1 TO 30
  4967.                 CALL MoveLayer(screenLayerInfo&,layer&,dx%,dy%)
  4968.             NEXT loop1%
  4969.         
  4970.         wiatlp:
  4971.             LOCATE 1,1
  4972.             5
  4973.             PRINT "Press any key to End"
  4974.             WHILE in$= ""
  4975.                 in$ = INKEY$
  4976.             WEND
  4977.         
  4978.         removeIt:
  4979.             CALL DeleteLayer(screenLayerInfo&, layer&)
  4980.             
  4981.         thatsIt:
  4982.             LIBRARY CLOSE
  4983.             END
  4984.         
  4985.                                 PAGE 189
  4986.         
  4987. -----------------------------------------------------------------------------
  4988.         
  4989. As you can see, our small layer acts much like a large window. When you 
  4990. move the mouse pointer over the layer and click the left mouse button, the
  4991. layer is activated and the window ripples. In order for the layer to be 
  4992. a complete window, it would need the frame, the gadgets and a menu.
  4993.         
  4994. When you press a key the layer completely dissappears.
  4995.         
  4996. To create the above program, we used functions from both the graphic and
  4997. layers libraries. However, the layers library is more important in this
  4998. application. The layers function, CreateUpFrontLayer, which generates our
  4999. layer, requires eight arguments and returns the start address of the layer
  5000. block to the BASIC program.
  5001.         
  5002.         layer&=CreateUpFrontLayer&(layerInfo&,bitmap&,x0%,y0%,x1%,y1%,
  5003.    typ%,sbitmap&)
  5004.         
  5005.         layer&     : The address of our new layer data block.
  5006.         layerInfo& : The address of the structure LayerInfo.
  5007.         bitmap&    : The address of the bit-map where the new layer is
  5008.                      to be produced.
  5009.         x0%,y0%    : Coordinates of the upper left hand corner of the 
  5010.                      layer.
  5011.         x1%,y1%    : Coordinates of the lower right hand corner.
  5012.         
  5013. The LayerInfo structure address and the bitmap structure address are found
  5014. in our well known screen structure (Section 3.6). By using the functions
  5015. text and move from the graphic library (see section 3.6.1), we can display
  5016. text through this RastPort.        
  5017.         
  5018. After studying the layer we close the layer again by using DeleteLayer.
  5019.         
  5020. Now we can take a look at the Layer's data structure. Just like every 
  5021. window, the layers also have this structure. It is constructed like 
  5022. this :
  5023.         
  5024.                                 PAGE 190
  5025.         
  5026. -----------------------------------------------------------------------------
  5027.         
  5028. Data Structure/Layer/layers/192 bytes.
  5029.         
  5030. Offset  Type    Description.
  5031. ------- ------- -------------------------------------------------------
  5032. +000    Long    Pointer to layer in foreground.
  5033. +004    Long    Pointer to layer in Background.
  5034. +008    Long    Pointer to first ClipRect.
  5035. +012    Long    Pointer to the first rastport of this layer.
  5036. +016     --     Rectangle structure, the limits of the layer.
  5037.                 +016   Word   MinX
  5038.                 +018   Word   MinY
  5039.                 +020   Word   MaxX
  5040.                 +022   Word   MaxY
  5041. +024    Byte    Lock
  5042. +025    Byte    LockCount
  5043. +026    Byte    LayerLockCount
  5044. +027    Byte    Reserved.
  5045. +028    Word    Reserved
  5046. +030    Word    Layer Flags.
  5047. +032    Long    Pointer to superbitmap, when available.
  5048. +036    Long    SuperClipRect
  5049. +040    Long    Pointer to Window
  5050. +044    Word    ScrollX
  5051. +046    Word    ScrollY
  5052. +048     --     Message Port "Lock Port"
  5053. +082     --     Message "LockMessage"
  5054. +102     --     Message Port "ReplyPort"
  5055. +136     --     Message " 1 LockMessage"
  5056. +156    Long    Pointer to first rectangle of DamageList
  5057. +160    Long    Pointer to ClipRects
  5058. +164    Long    Pointer to LayerInfo structure
  5059. +168    Long    Pointer to Task with actual lock
  5060. +172    Long    Pointer to SuperSaveClipRects
  5061. +176    Long    Pointer to CR ClipRects
  5062. +180    Long    Pointer to CR2 CLipRects
  5063. +184    Long    Pointer to CRNEW ClipRects
  5064. +188    Long    System use.
  5065.         
  5066.                 --------------------------------------------
  5067.         
  5068. 4.6.1 THE LAYER DATA STRUCTURE.
  5069.         
  5070. The data structure we just introduced requires further explanation.
  5071. We will examine it field by field with the same format we have been using.
  5072.         
  5073. To obtain the starting address for the layer of your actual output window
  5074. use the following:
  5075.         
  5076.                                 PAGE 191
  5077.         
  5078. -----------------------------------------------------------------------------
  5079.         
  5080.         layer& = PEEKL(WINDOW(8))
  5081.         
  5082. The startin address of the layer data structure you have created is 
  5083. automatically returned by the appropriate layer functions. Later we will
  5084. come back to this subject.
  5085.         
  5086. OFFSET 0 AND 4: POINTER TO OTHER LAYERS.
  5087.         
  5088. This pointer contains the startin address of the layer data block for a 
  5089. layer that is behind or in front of your layer. The same relationship
  5090. applies to layers as to windows; you can move from one layer to all other
  5091. layers in the system.
  5092.         
  5093. OFFSET 8: FIRST CLIPRECT
  5094.         
  5095. ClipRect is another data structure which ddescribes a current rectangular
  5096. pic of a layer. This pointer is to the first ClipRect structure of this 
  5097. layer, from which you can obtain the next and the following ClipRect
  5098. address. This chain of ClipRects describes the visible portion of this
  5099. layer.
  5100.         
  5101. OFFSET 12: THE RASTPORT
  5102.         
  5103. This offset contains the starting address of the RastPort for this layer.
  5104. Most functions of the graphic library require the RastPort address with 
  5105. which they will be working.
  5106.         
  5107. Since every Intuition window has a layer, it also has its own Layer 
  5108. RastPort. This RastPort is identical with the RastPort of the window data
  5109. structure:
  5110.         
  5111.         RastPort1& = PEEKL(WINDOW(7)+50)
  5112.         RastPort2& = WINDOW(8)
  5113.         layer& = PEEKL(WINDOW(8))
  5114.         RastPort3& = PEEKL(layer&+12)
  5115.         PRINT RastPort1&
  5116.         PRINT RastPort2&
  5117.         PRINT RastPort3&
  5118.         
  5119. The starting addresses returned for the RastPorts are the same.
  5120.         
  5121.         
  5122. OFFSET 16, 18, 20, and 22: BOUNDS
  5123.         
  5124. The X and Y values stored here set the layer limits. Any drawing function
  5125. that uses coordinates is clipped off if it passes outside there boundaries.
  5126. Let's first determine the limits of our own layers:
  5127.         
  5128.         windo& = WINDOW(7)
  5129.         RastPort& = WINDOW(8)
  5130.         layer& = PEEKL(RastPort&)
  5131.         
  5132.         
  5133.                                 PAGE 192
  5134.         
  5135. -----------------------------------------------------------------------------
  5136.         
  5137.         x0% = PEEKW(layer&+16)
  5138.         y0% = PEEKW(layer&+18)
  5139.         x1% = PEEKW(layer&+20)
  5140.         y1% = PEEKW(layer&+22)
  5141.         
  5142.         PRINT x0%,y0%
  5143.         PRINT x1%,y1%
  5144.         
  5145.         END
  5146.         
  5147. The result is the coordinates of the upper left hand and the lower right
  5148. hand corners of our drawing plane.
  5149.         
  5150. Naturally, you could use this method to define your own drawing plane.
  5151. Everything outside of this area would be clipped off.
  5152.         
  5153.         REM 4.6.1 Offsets 16-22 Example B
  5154.         
  5155.         PRINT "Searching for .bmap file..."
  5156.         
  5157.         init:
  5158.             '* Address of the data structures
  5159.             CLS
  5160.             windo&    = WINDOW(7)
  5161.             RastPort& = WINDOW(8)
  5162.             layer&    = PEEKL(RastPort&)
  5163.         
  5164.             '* Current Valid Limits.
  5165.             x0%       = PEEKW(layer&+16)
  5166.             y0%       = PEEKW(layer&+18)
  5167.             x1%       = PEEKW(layer&+20)
  5168.             y1%       = PEEKW(layer&+22)
  5169.         
  5170.             scrWidth% = x1% - x0%
  5171.             scrHeight% = y1% - y0%
  5172.             
  5173.             main: '* DEMO
  5174.             LINE (x0%,y0%)-(x1%,y1%),2,bf
  5175.             
  5176.             'Set new limits.
  5177.             nx0% = x0% + .25*scrWidth%
  5178.             nx1% = x1% - .25*scrWidth%
  5179.             ny0% = y0% + .25*scrHeight%
  5180.             ny1% = y1% - .25*scrHeight%
  5181.             
  5182.             POKEW layer&+16,nx0%
  5183.             POKEW layer&+18,ny0%
  5184.             POKEW layer&+20,nx1%
  5185.             POKEW layer&+22,ny1%
  5186.             
  5187.             ' It look like This:
  5188.             FOR test% = 0 TO 40
  5189.                 PRINT STRING$(50,"*")
  5190.             NEXT test%
  5191.             
  5192.             CLS
  5193.             
  5194.                                 PAGE 193
  5195.         
  5196. -----------------------------------------------------------------------------
  5197.         
  5198.             PRINT "Enter CONT!"
  5199.         
  5200.             STOP
  5201.             
  5202.             '* Restore original limits.
  5203.             POKEW layer&+16,x0%
  5204.             POKEW layer&+18,y0%
  5205.             POKEW layer&+20,x1%
  5206.             POKEW layer&+22,y1%
  5207.         END
  5208.         
  5209. OFFSET 24,25 AND 26: LOCK FIELDS.
  5210.         
  5211. The Amiga is a multi-tasking computer, which means that many programs can 
  5212. be running at the same time. So, it is possible for several programs to 
  5213. to attempt to access the same layer at the same time. These conflicting
  5214. access attempts would cause the program to abort. To prevent this from 
  5215. happening there are the layer functions, LockLayer and UnLockLayer. Through
  5216. these functions the tasks have unlimited access to the layers. As long as 
  5217. a task utilises Lock, another task cannot change the contents of the 
  5218. layer data structure.
  5219.         
  5220. These fields control the lock technique. The first field determines whether
  5221. this layer is currently locked. The second is a counter for the program 
  5222. that is now using the layer. The third is a counter that keeps track of
  5223. other tasks attempting access to the layer.
  5224.         
  5225.         
  5226. OFFSET 30: FLAGS.
  5227.         
  5228. There are various layer types that we will discuss shortly. This field
  5229. contains an identity flag for this layer:
  5230.         
  5231.         Bit 0 : 1 = LayerSimple
  5232.         Bit 1 : 1 = LayerSmart
  5233.         Bit 2 : 1 = Layersuper
  5234.         Bit 6 : 1 = Layerbackdrop
  5235.         Bit 7 : 1 = Layerrefresh
  5236.         
  5237.         
  5238. OFFSET 32 : SUPERBITMAP
  5239.         
  5240. A layer has its own drawing plane and bitmap when it is in the layersuper
  5241. mode. The pointer to these is stored in this offset. We will explain this
  5242. in detail later.
  5243.         
  5244.         
  5245. OFFSET 36: SUPERCLIPRECT
  5246.         
  5247. When they are used, the ClipRects for the superbitmap are here (see offset 
  5248. 8.)
  5249.         
  5250.                                 PAGE 194
  5251.         
  5252. -----------------------------------------------------------------------------
  5253.         
  5254. OFFSET 40: WINDOW
  5255.         
  5256. Normally layers are linked with Intuition windows. When this happens,
  5257. this pointer contains the address of the corresponding window data 
  5258. structure.
  5259.         
  5260. This field is extremely important when you wnat to integrate layers with 
  5261. existing windows. We are going to cover this in more detail shortly.
  5262.         
  5263.         
  5264. OFFSET 44 AND 46 : SCOLLING
  5265.         
  5266. The referenced drawing line for a layer of type layersuper can be much
  5267. larger than the layer limit parameters. You can then use the layer like
  5268. a peephole that moves around a giant graphic. More on this later.
  5269.         
  5270.         
  5271. OFFSETS 48 - 136 : MESSAGES AND MESSAGE PORTS.
  5272.         
  5273. Messages and message ports are handled by the EXEC.library. Different 
  5274. tasks can communicate with each other through the message and message 
  5275. ports, which are similar to a mailbox and transmitter. Messages are their
  5276. letters. The reply port is the mailbox and the other message port sends the
  5277. message.
  5278.         
  5279.         
  5280. OFFSET 156: DAMAGE LIST
  5281.         
  5282. We mentioned before that layers are responsible for restoring covered 
  5283. portions of windows once they are no longer covered. Because of this, we
  5284. have a damage list which consists of a chain of data structures called
  5285. "regions".  These regions represent the rectangular portions of a layer.
  5286. The damage list contains all the damaged portions of its own window
  5287. (or layer) that is overlapped by other windows (or layers).
  5288.         
  5289. The remaining offset fields contain system information that BASIC cannot
  5290. use.
  5291.         
  5292.                                 PAGE 195
  5293.         
  5294. -----------------------------------------------------------------------------
  5295.                 Now load part 3.
  5296. -----------------------------------------------------------------------------
  5297.  
  5298.